この新しいJava7のtry-with-resourcesコンストラクトは非常に優れています。または少なくとも、例外が発生して私の一日を台無しにするまでは良かったです。
私はついにそれを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の使用に戻りました。しかし、次に例外が発生したときは、正当な理由がないように見える1つのJava自体が出力するのではなく、期待の失敗が例外になります。
それで...try-with-resourcesをあきらめることなく、ここで適切なエラー報告を取得する方法はありますか?