这个新的Java 7 try-with-resources构造非常不错。至少,直到出现异常(exception)情况毁了我的一天,这还是很好的。
我终于设法将其简化为可重现的测试,该测试只使用JUnit + jMock。
@Test
public void testAddSuppressedIssue() throws Exception {
Mockery mockery = new Mockery();
final Dependency dependency = mockery.mock(Dependency.class);
mockery.checking(new Expectations() {{
allowing(dependency).expectedCall();
allowing(dependency).close();
}});
try (DependencyUser user = new DependencyUser(dependency)) {
user.doStuff();
}
}
// A class we're testing.
private static class DependencyUser implements Closeable {
private final Dependency dependency;
private DependencyUser(Dependency dependency) {
this.dependency = dependency;
}
public void doStuff() {
dependency.unexpectedCall(); // bug
}
@Override
public void close() throws IOException {
dependency.close();
}
}
// Interface for its dependent component.
private static interface Dependency extends Closeable {
void expectedCall();
void unexpectedCall();
}
运行此示例,我得到:
java.lang.IllegalArgumentException: Self-suppression not permitted
at java.lang.Throwable.addSuppressed(Throwable.java:1042)
at com.acme.Java7FeaturesTest.testTryWithResources(Java7FeaturesTest.java:35)
阅读文档时,他们似乎在说,如果您要向自身添加抑制的异常,则将触发此错误。但是我没有这样做,我只是在使用try-with-resources块。然后,Java编译器会生成看似非法的代码,从而使该功能实际上无法使用。
当然,当测试通过时,不会出现任何问题。当测试失败时,将发生异常。因此,既然我已经解决了最初发现的问题,我就恢复了使用try-with-resources的权限。但是,下次发生异常时,我宁愿将异常作为期望失败,而不是因为似乎没有充分的理由发出一个Java本身。
那么...有没有办法在这里获得正确的错误报告,而又不放弃尝试资源的方法?
最佳答案
看起来jMock从这两个方法中抛出相同的异常实例。这就是不用jMock可以复制它的方式:
public class Test implements Closeable {
private RuntimeException ex = new RuntimeException();
public void doStuff() {
throw ex;
}
public void close() {
throw ex;
}
}
try (Test t = new Test()) {
t.doStuff();
}
如果是这样,我认为这是jMock的问题,而不是Java编译器的问题。