我已经实现了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
是好还是不好。
感谢您的帮助!
答案 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中设置断点,您可能会发现缺少哪个类。