使用Android Studio,在测试一段使用线程的代码时,我找到了一个很好的解决方案来验证抛出异常。在测试和UncaughtExceptionHandler
的线程上使用join()
等待此线程完成。
这一切在正常的测试运行甚至是调试时都很完美。运行覆盖时会出现问题,UncaughtExceptionHandler
永远不会被引发异常调用,因此测试失败,因为它期望看到异常。
我的一个假设是线程运行的方式是它不会抛出未经检查的异常(即在其他地方捕获)但我不知道如何验证或解决问题,因为我无法同时调试和运行覆盖。
答案 0 :(得分:0)
要从其他线程执行断言,请查看ConcurrentUnit。它提供了一个Waiter
,通过它可以在主线程主要等待的任何线程中执行断言。任何断言失败都会导致测试失败,如预期的那样:
Waiter waiter = new Waiter();
new Thread(() -> {
waiter.assertEquals(foo, bar);
waiter.resume();
}).start();
// Wait for resume or an assertion failure
waiter.await();
答案 1 :(得分:0)
我不确定Android测试是否使用了我在胖客户端java中使用的相同的Junit api,但是我使用 ErrorCollector TestRule来拉取离线进程异常回到主测试线程, ExpectedException 来验证我是否得到了应该由执行产生的异常类型,消息和/或原因。
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ErrorCollector;
import org.junit.rules.ExpectedException;
public class ThreadExceptionTest {
@Rule
public ErrorCollector collector = new ErrorCollector();
@Rule
public ExpectedException exEx = ExpectedException.none();
@Test
public void doThreadTestFail() throws Exception {
Runnable r = new Runnable() {
@Override
public void run() {
try {
throw new RuntimeException("drat");
} catch (Exception ex) {
collector.addError(ex);
}
}
};
Thread th = new Thread(r);
th.start();
th.join();
}
@Test
public void doThreadTestPass() throws Exception {
exEx.expect(RuntimeException.class);
exEx.expectMessage("drat");
Runnable r = new Runnable() {
@Override
public void run() {
try {
throw new RuntimeException("drat");
} catch (Exception ex) {
collector.addError(ex);
}
}
};
Thread th = new Thread(r);
th.start();
th.join();
}
}