我在Logic逻辑
中有以下方法public class Logic implements ILogic {
@Override
public void doSomethingInterestingAsync(final int number,
final ICallback callback){
new Thread(new Runnable() {
@Override
public void run() {
callback.response(number+1);
}
}).start();
}
}
我通常使用
来调用它ILogic.doSomethingInterestingAsync(1, new ICallback() {
@Override
public void response(int number) {
System.out.println(String.format("response - %s", number));
}
});
现在我想对它进行单元测试。
所以我认为一个解决方案是CountDownLatch(在other SO线程中找到)
如下:
@Test
public void testDoSomethingInterestingAsync_CountDownLatch() throws Exception {
final CountDownLatch lock = new CountDownLatch(1);
ILogic ILogic = new Logic();
final int testNumber = 1;
ILogic.doSomethingInterestingAsync(testNumber, new ICallback() {
@Override
public void response(int number) {
assertEquals(testNumber + 1, number);
lock.countDown();
}
});
assertEquals(true, lock.await(10000, TimeUnit.MILLISECONDS));
}
效果很好。
但我也读过关于Mockito中的答案可能是更好的做法,
但我不能完全遵循这些例子
如何使用Mockito工具使用回调编写方法的单元测试?
谢谢。
答案 0 :(得分:2)
我不明白为什么你需要CountDownLatch
开始(根据你发布的代码来判断),所以我会在我的回答中跳过这个,随意添加一条评论来解释我的内容我失踪了。
我按如下方式测试:
@Test
public void testDoSomethingInterestingAsyncIncrementsParameter() {
ILogic logic = new Logic();
ICallback callback = mock(ICallback.class);
logic.doSomethingInterestingAsync(SOME_NUMBER, callback);
verify(callback, timeout(1000)).response(SOME_NUMBER + 1);
}
答案 1 :(得分:2)
CoundownLatch方法可以正常工作,但如果你的回调中的断言失败,测试仍然会成功。为什么?主测试线程不知道其他线程正在做什么 - 因此断言失败只有在主测试线程中出现时才会被注意到。
测试线程/异步代码的更好,更简单的方法是使用ConcurrentUnit之类的东西:
final Waiter waiter = new Waiter();
new Thread(() -> {
doSomeWork();
waiter.assertTrue(true);
waiter.resume();
}).start();
// Wait for resume() to be called
waiter.await(1000);
无需使用CountdownLatch和断言通过Waiter工作完成,如你所料。