職場ではJUnit 3を使用しており、ExpectedException
アノテーションはありません。これをラップするコードにユーティリティを追加したかったのです。
try {
someCode();
fail("some error message");
} catch (SomeSpecificExceptionType ex) {
}
だから私はこれを試しました:
public static class ExpectedExceptionUtility {
public static <T extends Exception> void checkForExpectedException(String message, ExpectedExceptionBlock<T> block) {
try {
block.exceptionThrowingCode();
fail(message);
} catch (T ex) {
}
}
}
ただし、Javaは、catchブロックで一般的な例外タイプを使用できないと思います。
Java制限を回避して、どうすればこのようなことができますか?
ex
変数がT
型であることを確認する方法はありますか?
Classオブジェクトを渡して、プログラムで確認することができます。
public static <T extends Exception> void checkForException(String message,
Class<T> exceptionType, ExpectedExceptionBlock<T> block) {
try {
block.exceptionThrowingCode();
} catch (Exception ex) {
if ( exceptionType.isInstance(ex) ) {
return;
} else {
throw ex; //optional?
}
}
fail(message);
}
//...
checkForException("Expected an NPE", NullPointerException.class, //...
再投球が必要かどうかはわかりません。再スローしてもテストは不合格/エラーになりますが、基本的には「期待どおりの例外が発生しなかった」ことを意味し、テスト環境エラーではなくプログラミングエラーを表すため、意味的にはそうなりません。
例外テストのイディオムを単純化しようとする衝動を理解していますが、真剣に:しないでください。あなたが思いつくすべての可能な選択は、病気よりも悪い治療法です。 特に JUnit 4の@ExpectedExceptionナンセンス!通常のJavaコードの単純な自明のビットとは対照的に、誰もがそれがどのように機能するかを学ぶ必要があります。悪いことに、それはあなたにラップする方法を与えません。例外をスローすることが予想されるテストの一部なので、前のセットアップ手順で同じ例外がスローされると、コードが壊れていてもテストは成功します。
Java Googleにいるエンジニアの間でこの問題について長い議論がありましたので、ここに長いダイアトリブを書くことができました(時間がないので申し訳ありません)。コンセンサスは、これらのクレイジーなソリューションはどれも価値がないということでした。
タイプパラメータを含むCatch句は使用できません:
http://docs.Oracle.com/javase/tutorial/Java/generics/restrictions.html#cannotCatch
まあ、それが予期された例外でない場合は、例外をキャッチして再スローするだけです。優れたコーディング慣行では通常、コードの成功パスは例外によって定義されるべきではないため、設計を再考する必要があるかもしれません。
ジェネリックは型ではありません。テンプレートではありません。 Javaでのコンパイル時の型チェックです。例外ブロックはタイプをキャッチします。キャッチ(例外e)またはキャッチ(スロー可能e)して、必要に応じてキャストできます。
また、ライブテンプレートをサポートするIDE(IntellJ IDEA for example のような)を使用して、ee -> [tab]
は、try/catch/ignoreを挿入して正しいものを入力できるようにします。