我有个方法要测试
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
,它直接以service.signup
的名字命名assertEquals(cb.res, "hello")
,而不是我想要的,我如何修复它?
发布于 2014-07-11 10:12:21
使用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");
发布于 2014-07-11 11:16:46
您没有正确地使用等待/通知模式。
A. notifyAll()应该使用与wait()相同的监视器进行同步。
B.生产者调用(=())不应该在同步块中
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");
https://stackoverflow.com/questions/24695109
复制相似问题