37

他の誰かが書いたコードで JUnit テストを実行しようとしていますが、例外にタイプがないように見えるため、例外をテストする方法がわかりません。

public Pirate(String name, int initialGold) throws Exception {
    if(initialGold < 0)
        throw new Exception("Init Gold must be >= 0");
    this.name = name;
    this.numGold = initialGold;
    this.health = Pirate.DEFAULT_HEALTH;
    this.isCursed = false;
}

私のJUnitコードスニペット:

@Test
public static void constructorTest() throws Exception{
    rodgers = new Pirate("Dread Pirate Rodgers", 10000);
    assertEquals("Dread Pirate Rodgers" , rodgers.getName());
    assertEquals(10000, rodgers.getNumGold());
    assertEquals(100, rodgers.getHealth());
    assertEquals(false, rodgers.getIsCursed());
}

@Test()
public static void exceptionTest() throws Exception{
    rodgers = new Pirate("Dread Pirate Rodgers" , -100);

}

expected = (何らかのタイプの例外) を test の括弧に入れる必要があることはわかっていますが、例外のタイプについてはわかりません。

4

4 に答える 4

110

@Test(expected=Xyz.class)実際には、JUnit 4.7 でRuleとを使用する代替手段があります。ExpectedException

テスト ケースでは、 でExpectedException注釈を付けたを宣言@Ruleし、デフォルト値の を割り当てますExpectedException.none()。次に、例外を期待するテストで、値を実際の期待値に置き換えます。これの利点は、醜い try/catch メソッドを使用せずに、例外内のメッセージが何であったかをさらに指定できることです。

@Rule public ExpectedException thrown= ExpectedException.none();

@Test
public void myTest() {
    thrown.expect( Exception.class );
    thrown.expectMessage("Init Gold must be >= 0");

    rodgers = new Pirate("Dread Pirate Rodgers" , -100);
}

この方法を使用すると、一般的な例外のメッセージが特定のものであるかどうかをテストできる場合があります。

追加 を使用するもう 1 つの利点はExpectedException、テスト ケースのコンテキスト内で例外をより正確にスコープできることです。テストで注釈のみを使用している場合@Test(expected=Xyz.class)、Xyz 例外は、テスト コード内の任意の場所 (テスト メソッド内のテスト セットアップまたは事前アサートを含む) でスローできます。これは、誤検知につながる可能性があります。

ExpectedException を使用するthrown.expect(Xyz.class)と、テスト中のメソッドを実際に呼び出す直前に、セットアップと事前アサートの後までの指定を延期できます。したがって、テストフィクスチャ自体ではなく、実際のメソッド呼び出しによってスローされる例外をより正確にスコープします。

JUnit 5 注:

JUnit 5 JUnit Jupiter は@Test(expected=...)@RuleExpectedException完全に削除しました。これらは新しい に置き換えられ、assertThrows()Java 8 とラムダ構文を使用する必要があります。 ExpectedExceptionJUnit Vintage を通じて JUnit 5 で引き続き使用できます。また、JUnit Jupiter は、 junit-jupiter-migrationsupport モジュールExpectedExceptionを使用して JUnit 4 を引き続きサポートしますが、追加のクラスレベルの注釈を追加した場合に限ります。@EnableRuleMigrationSupport

于 2013-05-23T23:02:07.417 に答える
20

@Testアノテーションでexpectedを使用するか明示的な catch ブロックを提供して、プログラム フローが期待どおりでない場合に失敗を発行することができます。

@Test(expected=Exception.class) // java.lang.Exception
public static void exceptionTest() throws Exception {
    rodgers = new Pirate("Dread Pirate Rodgers" , -100);
}

@Test
public static void exceptionTest() throws Exception {
    try {
        rodgers = new Pirate("Dread Pirate Rodgers" , -100);
        fail("should not reach this");
    } catch(Exception e) {
        // ok
    }
}

私の個人的な好みは最初の解決策です。

于 2013-05-23T21:09:49.943 に答える
9

JUnit 'expected' を使用して例外をテストできます。

@Test(expected = ExceptionYouWishToTestFor.class)  
public void divisionWithException() {  
    // Test Code
}

その後、コードでその特定の例外をスローするのはあなた次第です。

于 2013-05-23T21:01:49.913 に答える
7

Exception金がゼロ以上でない場合、私は を投げません。を投げますIllegalArgumentExceptionPirate負の量のゴールドを持つことは違法であるように思えます。

public Pirate(String name, int initialGold) {
    if(initialGold < 0)
        throw new IllegalArgumentException("Init Gold must be >= 0");

次に、JUnit テスト ケースで、IllegalArgumentException.

@Test(expected=IllegalArgumentException.class)
public static void exceptionTest() {
于 2013-05-23T21:02:55.743 に答える