为什么模拟不能与AsyncTask一起使用?
我正在使用ApplicationTestCase测试一个Android应用程序.我想模拟我的一个AsyncTasks(简化示例以显示问题):
I'm testing an Android app using an ApplicationTestCase. I want to mock one of my AsyncTasks (example simplified to show the problem):
public class Foo extends AsyncTask<Void,Void,Void> {
@Override
protected Void doInBackground(Void... unused) {
return null;
}
}
所以要设置我的测试,我做了以下事情:
So to set up my tests, I did the following:
private Foo mockFoo;
@Override
protected void setUp() throws Exception {
super.setUp()
mockFoo = mock(Foo.class);
createApplication();
}
然后进行实际测试:
public void testAsyncTaskMock() {
mockFoo.execute();
verify(mockFoo).execute();
}
但是mockFoo.execute();
运行时出现异常:
java.lang.NullPointerException: Attempt to invoke virtual method 'int android.os.AsyncTask$Status.ordinal()' on a null object reference
为什么模拟AsyncTask的技术不起作用?
请注意,删除createApplication();
会使问题在这种简单情况下消失,但是对于我的实际测试,我确实需要创建该应用程序.
Note that removing createApplication();
causes the problem to go away in this simple case, but for my actual testing I do need the application to be created.
AsyncTask.execute 是最终版本,并且
具体来说,这是因为Java可以在编译时解析链接,这意味着Mockito无法使用其生成的子类和方法重写来更改行为. Specifically, this is because Java can resolve the link at compile time, which means Mockito can't use its generated subclasses and method overrides to change the behavior. 您可以选择使用 Powermock ,它使用特殊的类加载器重写旧的行为,或者 Robolectric ,它执行相同的操作,但用特定于Android且易于测试的替代实现(阴影")替换类包括一个用于AsyncTask的. You may choose to use Powermock, which uses a special classloader to rewrite the old behavior, or Robolectric, which does the same but replaces classes with Android-specific test-friendly alternate implementations ("shadows") including one for AsyncTask.