JUnit 5:例外がスローされることを表明する方法は?


214

JUnit 5でメソッドが例外をスローすることを表明するより良い方法はありますか?

現在、テストが例外をスローすることを確認するために@Ruleを使用する必要がありますが、テストで複数のメソッドが例外をスローすると予想される場合は、これは機能しません。


1
それに例外をチェックすることJUnit5よりも柔軟であるためAssertJをチェックするためにあなたの興味があるかもしれない
user1075613

回答:


321

を使用するassertThrows()と、同じテスト内で複数の例外をテストできます。Java 8でラムダがサポートされているため、これはJUnitで例外をテストするための標準的な方法です。

パーJUnitのドキュメント

import static org.junit.jupiter.api.Assertions.assertThrows;

@Test
void exceptionTesting() {
    MyException thrown = assertThrows(
           MyException.class,
           () -> myObject.doThing(),
           "Expected doThing() to throw, but it didn't"
    );

    assertTrue(thrown.getMessage().contains("Stuff"));
}

11
古い学校から「私はJunit5についてあまり知らない、おそらくJava8について十分ではない」...これはかなり奇妙に見えます。さらに説明を追加していただけませんか。「テスト中の実際の「本番コード」のどこにあるのか...スローされるはずだ」のように?
GhostCat

1
() -> ゼロの引数を受け入れるラムダ式を指します。したがって、例外をスローすることが予想される「本番コード」は、ポイントされるコードブロック(つまり、throw new...中括弧内のステートメント)にあります。
Sam Brannen 2016年

1
通常、ラムダ式はテスト対象(SUT)と相互作用します。つまり、上記のように直接例外をスローすることは、デモンストレーションを目的としています。
Sam Brannen 2016年

1
expectThrowsは推奨されないようです。ドキュメントでは、代わりにassertThrows()を使用するようになりました。
depsypher '14 / 03/17

5
バージョン5.0.0-M4 以降、expectThrowsは使用できなくなりました。assertThrowsのみが許可されています。参照してくださいgithub.com/junit-team/junit5/blob/master/documentation/src/docs/...: '削除廃止予定Assertions.expectThrowsを()メソッドをAssertions.assertThrowsの賛成で()'
gil.fernandes

91

Java 8およびJUnit 5(Jupiter)では、次のように例外をアサートできます。使用するorg.junit.jupiter.api.Assertions.assertThrows

public static <T extends Throwable> T assertThrows(Class <T> expectedType、Executable executable)

提供された実行可能ファイルの実行がexpectedTypeの例外をスローし、その例外を返すことを表明します。

例外がスローされない場合、または異なるタイプの例外がスローされる場合、このメソッドは失敗します。

例外インスタンスに対して追加のチェックを実行しない場合は、戻り値を無視してください。

@Test
public void itShouldThrowNullPointerExceptionWhenBlahBlah() {
    assertThrows(NullPointerException.class,
            ()->{
            //do whatever you want to do here
            //ex : objectName.thisMethodShoulThrowNullPointerExceptionForNullParameter(null);
            });
}

そのアプローチでは、の機能インターフェイスを使用Executableorg.junit.jupiter.apiます。

参照:


1
これでトップへ!:ラムダにちょうど1行があります場合、これはまた、最新のJUnit 5とファーで最高の答えである、IntelliJのはさらにダウンラムダを凝縮さassertThrows(NoSuchElementException.class, myLinkedList::getFirst);
anon58192932

26

彼らはJUnit 5でそれを変更し(予想:InvalidArgumentException、実際:呼び出されたメソッド)、コードは次のようになります。

@Test
public void wrongInput() {
    Throwable exception = assertThrows(InvalidArgumentException.class,
            ()->{objectName.yourMethod("WRONG");} );
}

21

Junit5は例外をアサートする方法を提供します

一般的な例外とカスタマイズされた例外の両方をテストできます

一般的な例外シナリオ:

ExpectGeneralException.java

public void validateParameters(Integer param ) {
    if (param == null) {
        throw new NullPointerException("Null parameters are not allowed");
    }
}

ExpectGeneralExceptionTest.java

@Test
@DisplayName("Test assert NullPointerException")
void testGeneralException(TestInfo testInfo) {
    final ExpectGeneralException generalEx = new ExpectGeneralException();

     NullPointerException exception = assertThrows(NullPointerException.class, () -> {
            generalEx.validateParameters(null);
        });
    assertEquals("Null parameters are not allowed", exception.getMessage());
}

CustomExceptionをテストするサンプルはここにあります:例外コードサンプルをアサート

ExpectCustomException.java

public String constructErrorMessage(String... args) throws InvalidParameterCountException {
    if(args.length!=3) {
        throw new InvalidParameterCountException("Invalid parametercount: expected=3, passed="+args.length);
    }else {
        String message = "";
        for(String arg: args) {
            message += arg;
        }
        return message;
    }
}

ExpectCustomExceptionTest.java

@Test
@DisplayName("Test assert exception")
void testCustomException(TestInfo testInfo) {
    final ExpectCustomException expectEx = new ExpectCustomException();

     InvalidParameterCountException exception = assertThrows(InvalidParameterCountException.class, () -> {
            expectEx.constructErrorMessage("sample ","error");
        });
    assertEquals("Invalid parametercount: expected=3, passed=2", exception.getMessage());
}

1
JUnitが組み込み例外とカスタム例外を処理する方法に違いはありません。
raindev

9

これはもっと簡単な例だと思います

List<String> emptyList = new ArrayList<>();
Optional<String> opt2 = emptyList.stream().findFirst();
assertThrows(NoSuchElementException.class, () -> opt2.get());

get()ArrayListを含むオプションを呼び出すと、がスローされますNoSuchElementExceptionassertThrows予期される例外を宣言し、ラムダサプライヤーを提供します(引数を取りません。値を返します)。

@primeに彼の答えを感謝します。


1
メソッドassertThrowsはスローされた例外を返します。したがってNoSuchElementException e = assertThrows(NoSuchElementException.class, () -> opt2.get());、以下のようにして、必要な例外オブジェクトに対してあらゆる種類のアサーションを実行できます。
キャプテンマン

8

使用できますassertThrows()。私の例は、ドキュメントhttp://junit.org/junit5/docs/current/user-guide/

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

....

@Test
void exceptionTesting() {
    Throwable exception = assertThrows(IllegalArgumentException.class, () -> {
        throw new IllegalArgumentException("a message");
    });
    assertEquals("a message", exception.getMessage());
}

2

さらにシンプルなワンライナー。Java 8とJUnit 5を使用するこの例では、ラムダ式や中括弧は不要です

import static org.junit.jupiter.api.Assertions.assertThrows;

@Test
void exceptionTesting() {

    assertThrows(MyException.class, myStackObject::doStackAction, "custom message if assertion fails..."); 

// note, no parenthesis on doStackAction ex ::pop NOT ::pop()
}

1

実際、私はこの特定の例のドキュメントに誤りがあると思います。意図されているメソッドはexpectThrowsです

public static void assertThrows(
public static <T extends Throwable> T expectThrows(

3
「Assertions.assertThrows()を優先して、非推奨のAssertions.expectThrows()メソッドを削除しました。」
マーティン・シュローダー

Junit 5の場合は、org.testng.Assertではなくorg.junit.jupiter.api.Assertionsからのものであることを確認してください。私たちのプロジェクトにはJunitとTestNGの両方が含まれていて、assertExpectsに変更するまでassertThrowsがvoidエラーを返し続けました。私がorg.testng.Assertを使用していることがわかりました。
バリーク

-5

ここに簡単な方法があります。

@Test
void exceptionTest() {

   try{
        model.someMethod("invalidInput");
        fail("Exception Expected!");
   }
   catch(SpecificException e){

        assertTrue(true);
   }
   catch(Exception e){
        fail("wrong exception thrown");
   }

}

期待する例外がスローされたときにのみ成功します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.