Mockitoスローされた例外をモックしてアサートする方法は?


回答:


75

BDDスタイルソリューション(Java 8に更新)

Mockitoだけでは例外の処理に最適なソリューションではありません。Cock -ExceptionでMockitoを使用してください

Mockito + キャッチ例外 + AssertJ

given(otherServiceMock.bar()).willThrow(new MyException());

when(() -> myService.foo());

then(caughtException()).isInstanceOf(MyException.class);

サンプルコード

依存関係


2
「キャッチ例外」とは何ですか?リンクをお持ちですか?
ダンカンジョーンズ

なにcaughtException
Saif Masadeh

com.googlecode.catchexception.CatchException.caughtException;
了解しました。発端

212

最初に2番目の質問に答えます。JUnit 4を使用している場合は、テストに注釈を付けることができます

@Test(expected=MyException.class)

例外が発生したと断言します。そして、mockitoで例外を「モック」するには、次を使用します。

when(myMock.doSomething()).thenThrow(new MyException());

2
この方法は、状態のあるオブジェクトのメソッドをテストする場合には受け入れられません。たとえば、2回目に呼び出した場合に例外をスローするオブジェクトメソッドがあります。また、最初のメソッド呼び出しではなく、2番目のメソッド呼び出し中に例外がスローされることをテストする必要があります。最初のメソッド呼び出し(準備段階)中にMyExceptionをスローした場合、テストに失敗するはずです。しかし、このアプローチでは、どのメソッド呼び出し中に例外がスローされたかを確認できません。
Sneg

ただし、この場合は、最初のメソッド呼び出しから例外をキャッチして、RuntimeExceptionでラップできます。
Sneg

29

例外メッセージもテストしたい場合は、MockitoでJUnitのExpectedExceptionを使用できます。

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

@Test
public void testExceptionMessage() throws Exception {
    expectedException.expect(AnyException.class);
    expectedException.expectMessage("The expected message");

    given(foo.bar()).willThrow(new AnyException("The expected message"));
}

given()これはどこから来たのですか?
Mohammad Faisal


@Ruleを使用することも好みます。これにより、予期されるメッセージや原因、または例外に関連するその他のものをテストできます。例外の原因を確認するために、expectedException.expectCause(Mockito.sameInstance(expectedException))またはexpectedException.expectCause(Mockito.instanceOf(MyException.class))と便利な他のいくつかを使用します。
Crenguta S

19

2015年6月19日の回答を更新(Java 8を使用している場合)

assertjを使用するだけ

assertj-core-3.0.0 + Java 8 Lambdasの使用

@Test
public void shouldThrowIllegalArgumentExceptionWhenPassingBadArg() {
assertThatThrownBy(() -> myService.sumTingWong("badArg"))
                                  .isInstanceOf(IllegalArgumentException.class);
}

リファレンス:http : //blog.codeleak.pl/2015/04/junit-testing-exceptions-with-java-8.html


また、例外メッセージも確認できます.assertThatThrownBy(()-> myService.sumTingWong( "badArg"))。hasMessage( "test").isInstanceOf(IllegalArgumentException.class);
Sritam Jagadev

17

JUnit 4とMockito 1.10.xを使用している場合、テストメソッドに次のアノテーションを付けます。

@Test(expected = AnyException.class)

そして、あなたが望む例外を投げるには:

Mockito.doThrow(new AnyException()).when(obj).callAnyMethod();

16

このように例外を発生させます:

when(obj.someMethod()).thenThrow(new AnException());

テストがそのような例外をスローすることをアサートして、それが発生したことを確認します。

@Test(expected = AnException.class)

または通常の模擬検証:

verify(obj).someMethod();

中間コードが例外を処理することをテストが設計する場合は、後者のオプションが必要です(つまり、テストメソッドから例外がスローされません)。


verify例外アサート呼び出しは?
NilsH 2013

@NilsHいいえ。ただし、このwhen句が正しければ、例外がスローされているはずです。
ダンカンジョーンズ

10

MockitoのdoThrowを使用し、必要な例外をキャッチして、後でスローされたことをアサートします。

@Test
public void fooShouldThrowMyException() {
    // given
    val myClass = new MyClass();
    val arg = mock(MyArgument.class);
    doThrow(MyException.class).when(arg).argMethod(any());
    Exception exception = null;

    // when
    try {
        myClass.foo(arg);
    } catch (MyException t) {
        exception = t;
    }

    // then
    assertNotNull(exception);
}

5

mockitoを使用すると、例外を発生させることができます。

when(testingClassObj.testSomeMethod).thenThrow(new CustomException());

Junit5を使用して、例外をアサートし、テストメソッドが呼び出されたときにその例外がスローされるかどうかアサートできます。

@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());
}

ここでサンプルを検索:例外junitをアサート


よろしくお願いします!私のために働いた
HariKishore 2017年

1

mockitoとは関係なく、例外をキャッチしてそのプロパティをアサートできます。例外が発生したことを確認するには、例外をスローするステートメントの後のtryブロック内でfalse条件をアサートします。


@MariuszS応答は、Mockitoとは無関係であるとあなたが言っていることを正しく答えます
pringi

@pringiありがとう、私は質問が例外のモックとキャッチの両方に関係していることを理解しています。これはテスト対象のコードの動作に依存するのでしょうか。
eel ghEEz

1

または、クラスのコンストラクターから例外がスローされた場合:

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

@Test
public void myTest() {    

    exception.expect(MyException.class);
    CustomClass myClass= mock(CustomClass.class);
    doThrow(new MyException("constructor failed")).when(myClass);  

}

-1

例外メッセージでアサート:

    try {
        MyAgent.getNameByNode("d");
    } catch (Exception e) {
        Assert.assertEquals("Failed to fetch data.", e.getMessage());
    }

このように記述されている場合、スローされた例外がない場合でも、テストは合格します。それは私たちが最初に避けたいことです
クリスチャンリム
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.