测试异步任务时常常遇到后台线程还没完成,但测试线程已结束的情况。这时往往不能得到正确的测试结果。
最简单的办法是预估测试可能消耗的时间,比如为 5000毫秒,然后在开始测试后调用 Thread.sleep() 方法让测试线程休眠,防止测试过快结束。
public void testDoWork() throws Exception {
// 启动异步测试任务
doWork();
Thread.sleep(6000);
}
上面的做法主要问题是异步任务执行时间可能不确定,休眠时间无法预估。其实使用 CountDownLatch 可以非常优雅地解决这个问题,代码如下:
public class TestDummy extends TestCase {
private Dummy dummy;
@Override
protected void setUp() throws Exception {
super.setUp();
dummy = new Dummy();
}
public void testFoo() throws Exception {
final CountDownLatch signal = new CountDownLatch(2);
dummy.downloadInBg("正确的密码", new OnFinishListener() {
@Override
public void onFinish(boolean ok) {
assertTrue(ok);
signal.countDown();
}
});
dummy.downloadInBg("不正确的密码", new OnFinishListener() {
@Override
public void onFinish(boolean ok) {
assertFalse(ok);
signal.countDown();
}
});
signal.await();
}
}
class Dummy {
void downloadInBg(final String password, final OnFinishListener listener) {
new Thread() {
public void run() {
download(password, listener);
}
}.start();
}
void download(String password, OnFinishListener listener) {
try {
// 模拟建立连接
TimeUnit.SECONDS.sleep(1);
if (!password.equals("正确的密码")) {
throw new Exception();
}
// 模拟下载
TimeUnit.SECONDS.sleep(5);
listener.onFinish(true);
} catch (InterruptedException e) {
listener.onFinish(false);
} catch (Exception e) {
listener.onFinish(false);
}
}
interface OnFinishListener {
void onFinish(boolean ok);
}
}
参考: 在Android上测试异步任务