web-dev-qa-db-ja.com

TestNG:必須の例外をテストする方法は?

TestNGテストを作成して、特定の条件下で例外がスローされることを確認し、例外がスローされない場合はテストに失敗したいと思います。余分なブール変数を作成せずにこれを行う簡単な方法はありますか?

このテーマに関連するブログ投稿: http://konigsberg.blogspot.com/2007/11/testng-and-expectedexceptions-ive.html

20

@Test(expectedExceptions)は、最も一般的な場合に役立ちます。

  • 特定の例外がスローされることを期待しています
  • 特定の単語を含めるには、その例外のメッセージが必要です

ドキュメントによると、expectedExceptionがスローされない場合、テストは失敗します。

テストメソッドがスローすると予想される例外のリスト。例外がスローされないか、このリストにあるものとは異なるものがスローされた場合、このテストは失敗としてマークされます。

@Test(expectedExceptions)では不十分なシナリオをいくつか示します。

  • テストメソッドにはいくつかのステートメントがあり、そのうちの1つだけがスローされると予想されます
  • 独自のタイプの例外をスローしていて、それが特定の基準に一致することを確認する必要があります

このような場合は、従来の(TestNG以前の)パターンに戻す必要があります。

try {
  // your statement expected to throw
  fail();
}
catch(<the expected exception>) {
  // pass
}
25
Cedric Beust

使用する @Test予想される例外をチェックするための注釈。

@Test(
    expectedExceptions = AnyClassThatExtendsException.class,
    expectedExceptionsMessageRegExp = "Exception message regexp"
)

または、例外メッセージを確認したくない場合は、以下のみで十分です。

@Test(expectedExceptions = AnyClassThatExtendsException.class)

このように、醜いtry catchブロックを使用する必要はなく、テスト内でexception-throwerメソッドを呼び出すだけです。

10
harunurhan

私は、採用されたテスト手法の性質に関する記事に同意しなければなりません。このソリューションでは、ゲートを使用して、テストが中間段階で成功するか失敗するかを検証します。

私の意見では、特にそのようなテストには Guard Assertions を使用する方が良いと思います(テストが長く複雑であることが判明しないと仮定すると、それ自体がアンチパターンです)。ガードアサーションを使用すると、次のいずれかの方法でSUTを設計する必要があります。

  • 呼び出しが成功したか成功したかに関する結果に十分な情報を提供するようにメソッド自体を設計します。設計者の意図が結果を返さず、代わりに例外をスローすることであるため、これを実行できない場合があります(これは2番目のケースで処理できます)。
  • 重要なメソッドが呼び出されるたびに 状態を検証できる になるようにSUTを設計します。

ただし、上記の可能性を検討する前に、次のスニペットをもう一度見てください。

plane.bookAllSeats();
plane.bookPlane(createValidItinerary(), null);

BookPlane()をテストし、そのメソッドの実行を確認することを目的としている場合は、フィクスチャにbookAllSeats()を含めることをお勧めします。私の理解では、bookAllSeats()を呼び出すことは、bookPlane()の呼び出しが失敗することを保証するために、SUTを設定することと同等です。したがって、同じことを行うためのフィクスチャがあると、テストが読みやすくなります。意図が異なる場合は、(機能テストで通常行うように)移行のたびに状態をテストして、障害の元の原因を特定できるようにすることをお勧めします。

1
Vineet Reynolds

catch-exception は、予想される例外をテストするために必要なすべてのものを提供します。

0
rwitzel

リンク先のブログ投稿に記載されているtry/fail/catchパターンを使用してみませんか?

0
Thomas Lötzer

Java 7を使用していて、これをJava 8に使用できる場合は、ラムダ式を使用することもできます。

class A implements ThrowingRunnable{


            @Override
            public void run() throws AuthenticationFailedException{
                spy.processAuthenticationResponse(mockRequest, mockResponse, authenticationContext);
            }
        }
        assertThrows(AuthenticationFailedException.class,new A());
0