在测试期间阻止线程检查其状态的最佳方法是什么?

时间:2011-03-15 16:13:22

标签: java unit-testing mockito

使用Java进行测试(使用Mockito和Powermock但愿意使用任何可以解决此问题的方法)。我有一个具有以下签名的对象:

public class MyClass {
   public void doRun() {
      //Do work
   }

   public int numberComplete() {
      //Return number of items complete
   }
}

“doRun”方法获取项目列表并“完成”它们(每个都需要相当长的时间)。为了“获取”和“完成”一个项目,使用模拟管理器,所以我有如下测试:

@Test public void managerIsInformedOfEachFinishedItem() {
  task.doRun();
  verify(mockManager, times(3)).finish((Item)any());
}

最后,我可以调用“task.numberComplete()”并确实看到该任务返回3.但是,我真正想要做的是:

@Test public void managerIsInformedOfEachFinishedItem() {
  int count1, count2;
  when(mockManager.finish(item1).thenSet(count1 = task.numberComplete());
  when(mockManager.finish(item2).thenSet(count2 = task.numberComplete());

  task.doRun();

  assertEquals(1, count1);
  assertEquals(2, count2);
}

我意识到这可能不是已有的东西。但是如果你打算尝试实现这样的东西(无论语法如何 - 我不在乎测试最初的清洁程度如何),你会怎么做呢?任何建议/想法都表示赞赏!

1 个答案:

答案 0 :(得分:0)

您可以实现自己的模拟管理器,而不是使用管理器的第三方模拟框架,该管理器会在finish方法中为您进行验证。请记住,如果finish将在另一个线程中被调用,那么您不应该将assertEquals放在那里,因为该线程中抛出的AssertionError很可能会被忽略。相反,您可以将成功/失败结果存储在模拟管理器的成员变量(属性)中,然后从测试中检查。 (不要忘记同步对该共享结果值的访问权限,或使用atomic来保存它。)