6

多数の例外をスローする関数のテスト ケースを作成する場合、これらの例外のスロー宣言をテスト メソッドに追加するか、個々の例外を個別にキャッチする必要があります。それについての正しい方法は何ですか?try-catch の方が良い方法だと思いますが、catch ブロックでスタックトレースを出力する必要がありますか?

たとえば、をgetGroups(String name)スローするメソッドがありAuthenticationExceptionます。パラメーターが nullIllegalArgumentExceptionのときに がスローされるかどうかを確認するテスト ケースを作成した場合、どのように処理すればよいですか? メソッドのスロー部分に追加するか、例外をブロックで囲む必要がありますか。nameAuthenticationExceptiontry-catch

@Test
public void testGetGroupsWithNull() throws AuthenticationException {
 thrown.expect(IllegalArgumentException.class);
 getGroups(null);
}

上記のテスト ケースでは を追加しましたthrows AuthenticationExceptionが、例外を try-catch ブロックで囲む方がよいかどうか、および例外をキャッチした後に何をすべきかを知りたいです。スタックトレースを印刷できました。

AuthenticationException「throws」句ではなく、try/catch ブロックに配置することで、予期しない例外を処理しています。

@Test
public void testGetGroupsWithNull() {
thrown.expect(IllegalArgumentException.class);
try {
  getGroups(null);
} catch(AuthenticationExcption e) {
  Assert.fail("Authentication Exception");
}
}
4

5 に答える 5

5

JUnit のすばらしい記事がここにあります: https://github.com/junit-team/junit/wiki/Exception-testingはまさにこの主題に関するものです。できるよ:

@Test(expected= IndexOutOfBoundsException.class) 
public void empty() { 
  new ArrayList<Object>().get(0); 
}

また:

@Test
  public void testExceptionMessage() {
      try {
          new ArrayList<Object>().get(0);
          fail("Expected an IndexOutOfBoundsException to be thrown");
      } catch (IndexOutOfBoundsException anIndexOutOfBoundsException) {
          assertThat(anIndexOutOfBoundsException.getMessage(), is("Index: 0, Size: 0"));
      }
  }
于 2013-08-14T22:12:32.857 に答える
4

JUnit テストが予期しない例外をスローすると、失敗します。それがあなたが望む行動です。したがって、try/catch ブロックを使用する意味はありません。例外が予想される場合は、ExpectedException ルールを使用します (コード スニペットから明らかなように)。ただし、期待しているかどうかにかかわらず、try/catch は使用しないでください。

これは、例外がチェック済み例外である場合、throws 句が必要であることを意味します。実際、例外がスローされることを予期していない場合でも、テスト メソッドに throws 句が必要になることがよくあります。これは、テストで、チェック済み例外をスローできるメソッドが呼び出されることがあるためです。throws Exception私はすべてのテストメソッドについて書く習慣を身につけました。そうしない理由はありません。心配することが 1 つ減るだけです。

于 2013-08-14T22:30:19.537 に答える
1

注釈はよりコミュニケーション的です。

これは、リーダーにコードを読ませることなく、テストが何を期待しているかを知らせます。

各テストは単一の動作をテストする必要があるため、単一のテストでは単一の例外のみがスローされることを期待する必要があります。1 つの動作でスローできる例外は 1 つだけです。

他の例外がスローされた場合、それはテストの失敗です。テスト メソッドのシグネチャは、同じメソッドを呼び出す実際のコードと同様に、チェックされた可能性のある例外をすべて反映する必要があります。

于 2013-08-14T22:14:11.500 に答える
0

私はあなたのトピックを扱っているので、同じ質問を探していて、単体テストのベストプラクティスについての良い説明を見つけました. 記事から少し抜粋すると役立ちます。

JUnit フレームワークが状況を処理するため、テストに失敗するためだけに存在する独自の catch ブロックを記述する必要はありません。たとえば、次のメソッドの単体テストを作成しているとします。

final class Foo {
  int foo(int i) throws IOException;
}

ここには、整数を受け入れて整数を返し、エラーが発生した場合に IOException をスローするメソッドがあります。以下は、7 を渡されたときにメソッドが 3 を返すことを確認する単体テストを記述する間違った方法です。

// Don't do this - it's not necessary to write the try/catch!
@Test
public void foo_seven()
{
  try
  {
    assertEquals(3, new Foo().foo(7));
  }
  catch (final IOException e)
  {
    fail();
  }
}

テスト中のメソッドは、チェック例外である IOException をスローできることを指定します。したがって、例外をキャッチするか、テスト メソッドが例外を伝播できることを宣言しない限り、単体テストはコンパイルされません。2 番目の方法は、テストがより短く、より焦点を絞ったものになるため、推奨されます。

// Do this instead
@Test
public void foo_seven() throws Exception
{
  assertEquals(3, new Foo().foo(7));
}

テスト メソッドが IOException をスローするのではなく、Exception をスローすることを宣言します。JUnit フレームワークは、テスト中のメソッドの呼び出し中に例外が発生した場合、このテストが失敗することを確認します。独自の例外処理を記述する必要はありません。

上記のような JUnit のベスト プラクティスの詳細については、 http ://www.kyleblaney.com/junit-best-practices/ の記事を参照してください。

お役に立てれば幸いです。

于 2014-01-08T15:49:35.720 に答える