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!

4

2 回答 2

0

AVerifyError表示您正在尝试使用不同版本的库。在这种情况下,看起来 EasyMock 使用的 CGLib 版本与程序的其他部分不同。

我看到您提到您将 CGLib 添加到类路径中,如果首先找到另一个错误版本,您添加的版本可能不会被您的类加载器使用。我建议您将 CGLib jar 移动到类路径的前面,以便首先找到它。

如果您仍然收到错误,您可能需要使用相同版本的 CGLib 重新编译您的库。如果对 CGLib 的更改不兼容,这可能会导致编译时错误,因此您可能需要进行一些代码更改。

你是如何构建你的代码的?一些较新的构建工具(例如 Maven)可以为您解决这些问题。

于 2013-08-26T17:34:41.007 回答
0

根据您的堆栈跟踪,您在 android 上使用 EasyMock。Android 没有提供 Java6 的完整实现,尤其是缺少一些 java.beans 类(例如java.beans.PropertyDescriptor)。这些类有时被 cglib 使用。

如果您在 ClassProxyFactory.java:249 处设置断点,您可能会发现缺少哪个类。

于 2013-10-27T18:53:22.240 回答