小编典典

为什么模拟不能与AsyncTask一起使用?

java

我正在使用ApplicationTestCase测试一个Android应用程序。我想模拟我的AsyncTasks之一(示例简化为显示问题):

public class Foo extends AsyncTask<Void,Void,Void> {
  @Override
  protected Void doInBackground(Void... unused) {
    return null;
  }
}

因此,为了设置测试,我做了以下工作:

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();在这种简单情况下,删除会导致问题消失,但是对于我的实际测试,我确实需要创建应用程序。


阅读 249

收藏
2020-11-30

共1个答案

小编典典

AsyncTask.execute是final,Mockito无法模拟final类或方法

  • 无法模拟最终方法-执行它们的实际行为没有任何异常。Mockito无法警告您嘲笑最终方法,因此请保持警惕。

具体来说,这是因为Java可以在编译时解析链接,这意味着Mockito不能使用其生成的子类和方法重写来更改行为。

您可以选择使用Powermock(使用特殊的类加载器重写旧行为)或Robolectric,其功能相同,但是将类替换为Android特定的测试友好的替代实现(“影子”),包括AsyncTask的替代实现。

2020-11-30