0

I've realized a series of Unit Tests for an Android App. The thing is, I want my test to be independent from Server Errors or others recording expectations. It seems that Mocking Object is the solution.

I've started with EasyMock by following Vogella's tutorial: http://www.vogella.com/articles/EasyMock/article.html

The thing is I'm getting an error and I've been searching for an answer on the web but I can't find anything useful... There are not so many questions about EasyMock errors, however I found a post quite similar as mine but not enough helpful. I've also found another post talking about erros that can occur because of the asm version...

Anyway, it seems that the problem come from the cglib. I've searched on the EasyMock website for some explanation: I need Objenesis(1.2) and Cglib(2.2). I've added the .jar and follow Vogella's advices. But it's still not working...

I also want to know if Mocking an AsyncTask is a good thing or should I Mock an other method called by the AsyncTask onPostExecute().

The Error Log:

java.lang.VerifyError: net.sf.cglib.proxy.Enhancer
at org.easymock.internal.ClassProxyFactory.createEnhancer(ClassProxyFactory.java:249)
at org.easymock.internal.ClassProxyFactory.createProxy(ClassProxyFactory.java:159)
at org.easymock.internal.MocksControl.createMock(MocksControl.java:59)
at org.easymock.EasyMock.createNiceMock(EasyMock.java:139)
at com.c4mprod.bhost.test.TestStudioActivity.setUp(TestStudioActivity.java:65)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:529)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1448)

My setUp() Test Code:

 @Override
public void setUp() throws Exception{
    super.setUp();
    setActivityInitialTouchMode(true);

    Intent testIntent = new Intent();
    testIntent.setAction(StudioActivity.ACTION_BHOST);
    testIntent.putExtra(StudioActivity.EXTRA_USER_ID,525);//DEVICE'S USER
    setActivityIntent(testIntent);

    //asyncGeoloc is an instance of LocationTask an AsyncTask
    //The error comes from this line below...
    asyncGeoloc = createNiceMock(StudioActivity.LocationTask.class);

    mStudioActivity = getActivity();

    mWFBoasterPreviewFragment = new WeakReference<BoasterPreviewFragment>((BoasterPreviewFragment) mStudioActivity.getSupportFragmentManager().findFragmentById(R.id.fragment_preview));
    mWFStudioBoastPreviewFragment = new WeakReference<StudioBoastPreviewFragment>((StudioBoastPreviewFragment) mStudioActivity.getSupportFragmentManager().findFragmentById(R.id.fragment_layout));
    mWFRecordFragment = new WeakReference<RecordFragment>((RecordFragment) mStudioActivity.getSupportFragmentManager().findFragmentByTag(RecordFragment.TAG_FRAGMENT_NAME));

    mBoasterPreviewFragment = mWFBoasterPreviewFragment.get();        
    mStudioBoastPreviewFragment = mWFStudioBoastPreviewFragment.get(); 
    mRecordFragment = mWFRecordFragment.get();        
}

My Geolocation Test Code:

public void testGeolocalistationLabel(){
    ActivityMonitor activityMonitor = getInstrumentation().addMonitor(StudioActivity.class.getName(), null, false);
    //My doInBackground() takes a LocationManager in param  
    LocationManager lLocation = (LocationManager) mStudioActivity.getSystemService(getInstrumentation().getTargetContext().LOCATION_SERVICE);
    expect(asyncGeoloc.doInBackground(lLocation)).andReturn("JUnit, Location");
    replay(asyncGeoloc);

    mStudioActivity.runOnUiThread(new Runnable() {
        @Override
        public void run(){
            mStudioBoastPreviewFragment.getGeoloc().performClick();
        }
      }); 

    StudioActivity lStudioActivity = (StudioActivity) getInstrumentation().waitForMonitorWithTimeout(activityMonitor,5000);         
    assertEquals("JUnit, Location",mStudioBoastPreviewFragment.getGeolocTextView().getText());
}

Well, if someone have more info about it or can answer me about is it good or not to Mock AsyncTask.

Thanks for the help!

GiyommStarsky
  • 31
  • 1
  • 6

2 Answers2

0

A VerifyError means you are trying to use different versions of a library. In this case, it looks like EasyMock is using a different version of CGLib than some other part of your program.

I see you mentioned that you added CGLib to your classpath, that version you added might not get used by your classloader if the other wrong version is found first. I recommend that you move the CGLib jar to the front of your classpath so it is found first.

If you are still getting the error, you may need to recompile your libraries using the same version of CGLib. This may cause compile time errors if the changes to CGLib are not compatible, so you might need to make some code changes.

How are you building your code? Some of the newer build tools like Maven can manage these problems for you.

dkatzel
  • 31,188
  • 3
  • 63
  • 67
0

According to your stack-trace you are using EasyMock on android. Android does not come with the full implementation of Java6, especially some java.beans classes are missing (e.g. java.beans.PropertyDescriptor). These classes are sometimes used by cglib.

If you set a breakpoint at ClassProxyFactory.java:249 you will probably find out which class is missing.

Sebastian
  • 877
  • 1
  • 9
  • 20