当前位置: 首页 > 面试题库 >

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

洪璞瑜
2023-03-14
问题内容

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


问题答案:

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

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

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

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



 类似资料:
  • 问题内容: 在下面的代码中,我试图使h1元素具有最高利润。当我在css中将位置设置为inline时,未显示上边距。但是,当我将其更改为inline-block时,它确实可以。我想知道是否有人可以解释为什么会这样。谢谢。 这是我的HTML: 这是CSS 问题答案: CSS2规范的9.2.4节规定: inline-block 此值使元素生成一个 内联级块容器 。内联块的内部被格式化为块框,元素本身被格

  • 问题内容: 我在使用JMockit(1.21)模拟时遇到问题。请参阅以下内容,以简化我的实际课程。基本上我在我的代码中使用了某个地方,我希望对其进行模拟。 至于我的测试代码,此测试有效。 该测试失败。 我收到的错误消息: 我可以嘲笑像其他系统类和这样的,但只是似乎没有工作(也没有为此事)。我知道如何规避这是我的考验,所以我没有受到任何阻碍,但我不明白为什么不能嘲笑。删除Expectations块将

  • 问题内容: 我已经在端口8080(默认)下启动并测试了Tomcat。现在,我将连接器端口更改为80,并重新启动了Tomcat,在最小的Debian 6.0安装中没有任何显示。现在,这里的窍门在哪里? 问题答案: 转到/ etc / default / tomcat6并更改为

  • 问题内容: 我有两个档案 秒杀 test_spike.py: 当我运行时,第一个测试用例将通过,但是第二个将失败。而我切换到use ,则两个都失败了。 我不明白这是怎么发生的?这些情况本应全部通过。 问题答案: 对于 test_foo, 您没有正确使用补丁。您应该像这样使用它: 这给了我: 现在,第二个示例不起作用,因为您导入了bar函数(获取对其的引用),然后尝试对其进行模拟。模拟某些内容时,您

  • 问题内容: 有人可以向我解释为什么在这个简单示例中我无法获得当前选择的单选按钮。我正在尝试使用ng-repeat指令动态生成单选按钮,并使用ng- model获取当前选择的单选按钮。像这样: 模板: 控制器: 问题答案: 因为当它在放置指令的位置重复模板时,确实会在每次迭代中创建一个新的子范围(通常是继承的)。 那么当创建一个新的原型继承的子范围时会发生什么呢? 在子作用域中,它包含所有属性,其中

  • 问题内容: 我已经在端口8080(默认)下启动并测试了Tomcat。现在,我将连接器端口更改为80,然后重新启动了Tomcat,在最小的Debian 6.0安装中没有任何显示。现在,这里的窍门在哪里? 问题答案: 转到/ etc / default / tomcat6并更改为