我有一个测试方法
Service.signup(String username, String password, Callback listener);
我写了一个MockCallback来获得响应
class MockCallback implements Callback {
String res;
public void done(String res) {
this.res = res;
this.notifyAll()
}
}
我为它编写了一个测试用例,我必须等待Service.signup
完成,才能测试结果。
MockCallback cb = new MockCallback();
sychronized(cb) {
cb.wait();
service.signup("foo", "bar", cb);
}
assertEquals(cb.res, "hello");
但它不能按照我的预期运作,cb.res
是null
,它在assertEquals(cb.res, "hello")
之后立即调用service.signup
,而不是我想要的,我该如何解决?
答案 0 :(得分:0)
使用CountDownLatch
:
class MockCallback implements Callback {
private final CountDownLatch latch;
String res;
public MockCallback(CountDownLatch latch) { this.latch = latch; }
public void done(String res) {
this.res = res;
latch.countDown();
}
}
在你的测试用例中:
CountDownLatch latch = new CountDownLatch();
MockCallback cb = new MockCallback(latch);
service.signup("foo", "bar", cb);
latch.await(); // wait for latch to count down
assertEquals(cb.res, "hello");
答案 1 :(得分:0)
您没有正确使用等待/通知模式。
A。 notifyAll()
B。生产者调用(= signup())不应位于同步块内
C。 wait()应该包含一个任务完成的测试循环,在你的情况下应该测试res!= null。
D。而且,让所有同步监视器成为最终的真的好主意
这样的事情:
class MockCallback implements Callback {
String res;
public synchronized void done(String res) { //<----------- now synchronized
this.res = res;
this.notifyAll()
}
}
final MockCallback cb = new MockCallback(); //<----------- make monitor obj final
service.signup("foo", "bar", cb); //<----------- call not synchronized
sychronized(cb) {
while (cr.res == null) { //<------------- wait in loop and check completion condition
cb.wait();
}
}
assertEquals(cb.res, "hello");