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;并从那里开始工作!
我倾向于尽可能多地抛出已检查的 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;并从那里开始工作!