JUnit 对 RuntimeException 的处理(特别是)

JUnit handling of RuntimeException (specifically)

我倾向于尽可能多地抛出已检查的 Exceptions:它整理了代码(我认为已检查的 Exceptions 是 Java 的可疑方面)。我倾向于在 "refining" 代码时使用它们.. 即当它对特定上下文有意义时。

当重写 superclass/interface 不抛出必要 Exception 的方法时,这种方法会变得稍微复杂一些,因此我倾向于这样做:

@Override
public void close() {
    try {
        _close();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

其中 _close 是完成所有业务的私有方法。

关于 JUnit 的问题,如果你真的想测试 _close() 抛出异常的东西,结果 RuntimeException 似乎由 JUnit 在 "unconditional"方式:似乎总是以失败消息停止测试......即使你实际上在try .. catch中捕获并处理它!

我发现了一种 "workaround"(CUT class 在关闭时关闭所有 closeableComponents):

@Test (expected = RuntimeException.class)
public void errorFlagShouldBeSetIfAnyCloseablesThrowExceptionWhenCUTCloses() throws Exception {
    Closeable spyCloseable = spy( new Closeable(){
        @Override
        public void close() throws IOException {
            throw new IOException( "dummy" );
        }});
    spyCUT.addCloseableComponent( spyCloseable );
    Exception blob = null;
    try{
        spyCUT.close();
    }catch( Exception e ){
        blob = e;
    }
    assertThat( spyCUT.getErrorFlag() ).isTrue();
    if( blob != null ){
        throw blob;
    }

即如果你没有这个 expected 设置,你总是会得到一个测试失败(因为 RuntimeException "ignoring" try .. catch)。但是为了满足 expected 你必须在测试结束时重新抛出 RuntimeException...

...有什么方法可以改变 JUnit 对 RuntimeExceptions 的处理方式吗?

你的设置一定有问题。 JUnit 没有 对运行时异常进行任何此类特殊处理。

我整理了这个MCVE; 通过.

static class CUT {
    void close(Closeable _close) {
        try {
            _close.close();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

@Test
public void test() throws Exception {
    Closeable spyCloseable = Mockito.spy(new Closeable() {
        @Override
        public void close() throws IOException {
            throw new IOException("dummy");
        }
    });
    Exception blob = null;
    try {
        new CUT().close(spyCloseable);
        fail("should have thrown");
    } catch (Exception e) {
        blob = e;
    }
    assertThat(blob.getMessage(), is("java.io.IOException: dummy"));
}

这和你上面的不完全一样;但 "close enough" 在我看来。

长话短说:您的答案来自其他地方。我建议:像我一样做:创建一个 true mcve;并从那里开始工作!