[解決済み】例外がスローされないことをテストする方法は?
質問
というのも一つの方法だとは思いますが。
@Test
public void foo() {
try {
// execute code that you expect not to throw Exceptions.
} catch(Exception e) {
fail("Should not have thrown any exception");
}
}
何かもっと簡単な方法はないでしょうか?(おそらくJunitの
@Rule
?)
解決方法は?
アプローチの仕方が間違っています。もし例外が投げられたら、テストは自動的に失敗します。例外がスローされない場合、テストはすべて緑色になります。
この質問には時々関心があるようなので、少し話を広げます。
ユニットテストの背景
ユニットテストを行う場合、何をもって1つの作業単位と考えるかを自分自身で定義することが重要です。基本的には、コードベースから抽出したもので、複数のメソッドやクラスが含まれていてもいなくても、ひとつの機能を表すものです。
または、以下のように定義されています。 ユニットテストの技術 第2版 ロイ・オシェロブ著 11ページ
<ブロッククオートA 単体テスト は、テストされる作業単位を呼び出して、その作業単位の最終結果に関するいくつかの仮定をチェックする自動化されたコードの一部です。ユニットテストは、ほとんどの場合、ユニットテストフレームワークを使って書かれます。ユニットテストは、簡単に書くことができ、素早く実行することができます。信頼性が高く、読みやすく、保守しやすい。プロダクションコードが変更されていない限り、その結果には一貫性があります。
重要なのは、1つの ユニットワーク 通常、1つのメソッドだけでなく、非常に基本的なレベルでは1つのメソッドであり、その後、他の作品単位にカプセル化されます。
理想的なのは、個別の作業単位ごとにテストメソッドを用意し、どこで問題が起きているのかを常に確認できるようにすることです。この例では、基本的なメソッドである
getUserById()
はユーザーを返し、合計3つのユニットオブワークがあります。
最初の作業単位は、有効な入力と無効な入力の場合に、有効なユーザーが返されるかどうかをテストする必要があります。
データソースがスローする例外は、すべてここで処理しなければなりません。 ユーザーが存在しない場合は、ユーザーが見つからないときに例外がスローされることを示すテストが必要です。そのサンプルとして
IllegalArgumentException
でキャッチされる
@Test(expected = IllegalArgumentException.class)
アノテーションを使用します。
この基本的な作業単位ですべてのユースケースを処理したら、レベルを上げていきます。ここでは、まったく同じことを行いますが、現在のレベルのすぐ下のレベルに由来する例外のみを処理します。こうすることで、テストコードの構造が保たれ、あちこちに飛び回ることなく、アーキテクチャを素早く実行して、どこで問題が発生したかを見つけることができます。
テストの有効入力と異常入力の処理
この時点で、これらの例外をどのように処理するかは明確になっているはずです。入力には2つのタイプがあります。 有効 入力と 不具合 の入力(入力は厳密な意味では有効だが、正しくない)。
で作業する場合 有効 を入力すると、どんなテストを書いてもうまくいくことを暗黙のうちに期待していることになります。
このようなメソッド呼び出しは、次のようなものになります。
existingUserById_ShouldReturn_UserObject
. もしこのメソッドが失敗したら(例えば例外が投げられたら)、何かがうまくいかなかったとわかるので、調査を始めることができます。
別のテスト(
nonExistingUserById_ShouldThrow_IllegalArgumentException
を使用します。
不具合
を入力し、例外を期待することで、間違った入力に対してメソッドが想定したとおりに動くかどうかを確認することができます。
TL;DR
あなたのテストでは、有効な入力と欠陥のある入力をチェックするという2つのことを行おうとしていました。これを 2 つのメソッドに分割し、 それぞれがひとつのことを行うようにすれば、より明快なテストができ、 どこで問題が発生するのかをよりよく把握することができます。
階層化された作品単位を念頭に置くことで、階層が上のレイヤーで必要なテストの量を減らすこともできます。なぜなら、下のレイヤーでうまくいかなかったかもしれないことをすべて考慮する必要がないからです。現在のレイヤーより下のレイヤーは、依存関係が機能していることを事実上保証しており、もし何かがうまくいかないなら、それは現在のレイヤーにあります(下のレイヤー自身がエラーを投げないと仮定してですが)。
関連
-
[解決済み] プライベートメソッド、フィールド、インナークラスを持つクラスをテストするにはどうすればよいですか?
-
[解決済み] Pythonで例外を手動で発生(スロー)させる
-
[解決済み] 複数の例外を一度にキャッチする?
-
[解決済み] JUnit 4のテストで、ある例外が投げられたことをどのように断言しますか?
-
[解決済み] Pythonの関数が例外を投げるかどうかをテストするにはどうすればよいですか?
-
[解決済み] voidメソッドが例外を投げるかどうかをMockitoがテストする
-
[解決済み] 例外を発生させるタイミングは?
-
[解決済み】ネストされたディレクトリを安全に作成するには?
-
[解決済み】典型的なテストディレクトリ構造でunittestを実行する
-
[解決済み】JUnit 5:例外がスローされたことをアサートする方法は?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] tempとは何ですか、またjavaにおけるtempの用途は何ですか?
-
[解決済み] Eclipse デフォルトのフォント名
-
[解決済み] java.util.concurrent.ExecutionException 例外をどのように処理しますか?
-
[解決済み] java.lang.ClassNotFoundException: クラス com.ibm.db2.jcc.DB2Driver が Worklight プラットフォームまたはプロジェクトに見つかりませんでした。
-
[解決済み] 親から継承したメソッドの可視性を下げることができない [重複]。
-
[解決済み] java.util.MissingFormatArgumentException: 形式指定子 '%s' がありません。
-
[解決済み] HTTP ステータス 500 - サーブレットクラス pkg.coreServlet のインスタンス化に失敗しました。
-
[解決済み] Mavenです。JARは空になります - 含有するためにマークされたコンテンツがありません
-
[解決済み] タイプの安全性。アンチェック・キャスト
-
[解決済み] java.io.IOException。DER長の短い読み取り