我有一个非常简单的
在内部,
所以我的第一个想法是通过模拟测试
所以我在想,这是否值得想象中的麻烦:一个测试用例创建一个带有
问题总结:
Check
类,其中有一个阻塞的waitForCondition()
方法。该方法是阻塞的。我想为这个方法创建一些单元测试。首先,当条件满足时,该方法应该返回。其次,当被中断时,该方法应该返回。在内部,
Check
类具有一个ArrayBlockingQueue
并调用其take()
方法,因此我的测试实际上是关于正确编写条件逻辑(应该如此)的问题。
在应用程序中,Check
类的数据通过另一个线程通过InputData
方法提供。 InputData
方法在传入数据上执行逻辑,并在满足条件时在ArrayBlockingQueue中放置一个虚拟对象。这应该导致waitForCondition()
返回。所以我的第一个想法是通过模拟测试
InputData
并检查当满足条件时是否将虚拟对象添加到队列中。这将需要更改类的设计,因为队列是一个私有数据成员(除非可能模拟私有数据)。当条件满足时,InputData
不再直接添加到队列中,而是必须调用某个可模拟的东西。
但是,如果InputData
正常工作,检查waitForCondition()
方法本身就会出现问题。它真的很简单:
try {
myArrayBlockingQueue.take();
return true;
} catch (InterruptedException ex) {
return false;
}
所以我在想,这是否值得想象中的麻烦:一个测试用例创建一个带有
Check
的另一个线程,调用其waitForCondition()
,然后在完成时返回一些内容。也许可以使用Executor服务。模糊的部分是如何同步assertTrue(...)
。我发现了这篇异步测试文章 article on asynchronous testing,看起来它可能会起作用。问题总结:
- 我应该更改设计以测试
InputData()
中的逻辑,如果是这样,应该怎么做? - 只要测试了
InputData()
,就可以省略对waitForCondition()
的测试吗? - 还是直接执行需要执行的操作(一种有点复杂的单元测试),并直接测试
waitForCondition()
更好?
Check
类添加了一个构造函数,按照你建议的方式注入队列。然后,通过直接设置和读取实际队列(而不是模拟),我能够测试所有公共方法。只需要使用一个Mock来测试InterruptedException。使用Mockito:when(queueMock.take()).thenThrow(new InterruptedException());
所以,在这种情况下,我们可以完全避免任何异步/定时问题进行测试。 - Pete