具有Coverage的单独线程上的Junit异常

时间:2016-07-19 14:01:30

标签: java android multithreading android-studio junit

使用Android Studio,在测试一段使用线程的代码时,我找到了一个很好的解决方案来验证抛出异常。在测试和UncaughtExceptionHandler的线程上使用join()等待此线程完成。

这一切在正常的测试运行甚至是调试时都很完美。运行覆盖时会出现问题,UncaughtExceptionHandler永远不会被引发异常调用,因此测试失败,因为它期望看到异常。

我的一个假设是线程运行的方式是它不会抛出未经检查的异常(即在其他地方捕获)但我不知道如何验证或解决问题,因为我无法同时调试和运行覆盖。

2 个答案:

答案 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();

    }
}