我在提出这个问题的过程中想到了这一点,但我认为这对于将来遇到同样奇怪怪癖的人来说是一个很好的资源。将其视为对您的调试技能的挑战。
目前使用最新的 JUnit 4.12,这个特殊的测试既可以通过也可以失败——这取决于你如何看待它。运行它会打印出错误消息 - 但尽管 failed()
被调用,它仍然不会完全算作失败。
import java.io.IOException;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
public class TestWatcherExpectedExceptionTest {
@Rule
public TestWatcher logger = new TestWatcher() {
@Override
protected void failed(Throwable e, Description d) {
System.out.println(d + " FAILED! - are you kidding me ?");
e.printStackTrace();
}
@Override
protected void succeeded(Description d) {
System.out.println(d + " succeeded!");
}
};
@Rule
public ExpectedException thrown = ExpectedException.none();
/**
* This test both passes and fails, depending how you look at it.
*/
@Test
public void photon() throws IOException {
thrown.expect(IOException.class);
throw new IOException("Hi");
}
}
作为一个额外的奖励问题,在调试这个问题时,测试突然开始成功,并调用了 succeeded()
方法,我一直想不通为什么.据我所知,没有对代码进行可能产生任何影响的更改:
import java.io.IOException;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
public class TestWatcherExpectedExceptionTest {
private final class TestLogger extends TestWatcher {
@Override
protected void failed(Throwable e, Description d) {
System.out.println(d + " FAILED! - are you kidding me ?");
e.printStackTrace();
}
@Override
protected void succeeded(Description d) {
System.out.println(d + " succeeded!");
}
}
@Rule
public TestWatcher watcher = new TestLogger();
@Rule
public ExpectedException thrown = ExpectedException.none();
/**
* This test both passes and fails, depending how you look at it.
*/
@Test
public void photon() throws IOException {
thrown.expect(IOException.class);
throw new IOException("Hi");
}
}
最佳答案
关于为什么第二个测试有效以及为什么第一个测试完全失败的特殊答案在于 JUnit 处理规则的方式 - 显然,规则是根据字段名称和 TestWatcher 按字母顺序处理的
规则与 ExpectedException
规则不太兼容,因为如果规则被 JUnit 过早“解释”,它会忽略预期的异常。
所以第二个测试没有失败的原因在于字段名称 - watcher
按字母顺序出现在 thrown
之后,但是第一个测试的字段名称 logger
,出现在 thrown
之前。那个调试起来并不有趣。
关于java - JUnit 测试既通过又失败 - 使用 ExpectedException 和 TestWatcher @Rule's 发生冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43088543/