EasyMock错误:java.lang.VerifyError:net.sf.cglib.proxy.Enhancer

时间:2013-05-24 15:02:15

标签: android junit easymock cglib

我已经实现了Android应用程序的一系列单元测试。问题是,我希望我的测试独立于服务器错误或其他记录期望。似乎Mocking Object就是解决方案。

我按照Vogella的教程开始使用EasyMock:http://www.vogella.com/articles/EasyMock/article.html

问题是我收到了错误,我一直在网上寻找答案,但我找不到任何有用的东西......关于EasyMock错误没有太多问题,但是我发现了一个帖子和我的很相似,但不够有用。我还发现了另一篇关于因为asm版本而可能发生的错误的帖子......

无论如何,似乎问题来自cglib。我在EasyMock网站上搜索了一些解释:我需要Objenesis(1.2)和Cglib(2.2)。我添加了.jar并遵循Vogella的建议。但它仍然无法正常工作......

我也想知道模拟AsyncTask是好事还是我应该模拟AsyncTask onPostExecute()调用的其他方法。

错误日志:

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)

我的setUp()测试代码:

 @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();        
}

我的地理位置测试代码:

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());
}

好吧,如果有人有更多关于它的信息或者可以回答我关于Mock AsyncTask是好还是不好。

感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

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

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

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

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

答案 1 :(得分:0)

根据您的堆栈跟踪,您在Android上使用EasyMock。 Android没有完全实现Java6,特别是缺少一些java.beans类(例如java.beans.PropertyDescriptor)。这些类有时由cglib使用。

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