Mockito Bagaimana cara mengejek dan menyatakan pengecualian?


Jawaban:


75

Solusi Gaya BDD (Diperbarui ke Java 8)

Mockito sendiri bukan solusi terbaik untuk menangani pengecualian, gunakan Mockito dengan Catch-Exception

Mockito + Catch-Exception + AssertJ

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

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

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

Kode sampel

Ketergantungan


2
Apa itu "pengecualian menangkap"? Punya tautan?
Duncan Jones

apa caughtException?
Saif Masadeh

Mengerti, itu berasal daricom.googlecode.catchexception.CatchException.caughtException;
Saif Masadeh

212

Untuk menjawab pertanyaan kedua Anda terlebih dahulu. Jika Anda menggunakan JUnit 4, Anda dapat membuat anotasi dengan tes Anda

@Test(expected=MyException.class)

untuk menegaskan bahwa pengecualian telah terjadi. Dan untuk "mengejek" pengecualian dengan mockito, gunakan

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

2
pendekatan ini tidak dapat diterima untuk kasus ketika Anda menguji metode objek yang memiliki beberapa keadaan. Misalnya ada metode objek yang melempar pengecualian jika Anda menyebutnya yang kedua kalinya. Dan Anda perlu menguji untuk menguji apakah ia melempar pengecualian selama pemanggilan metode kedua, bukan yang pertama. Jika itu melempar MyException selama pemanggilan metode pertama (dalam tahap persiapan) maka harus gagal tes. Tetapi dengan pendekatan ini kami tidak dapat memeriksa selama panggilan metode pengecualian dilemparkan.
Sneg

Meskipun dalam kasus ini kita dapat menangkap pengecualian dari pemanggilan metode pertama dan membungkusnya dalam RuntimeException.
Sneg

29

Jika Anda ingin menguji pesan pengecualian juga, Anda dapat menggunakan JUnit's ExpectedException dengan Mockito:

@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()dari mana ini berasal?
Mohammad Faisal


Saya juga lebih suka menggunakan aturan @, karena dengan cara ini saya bisa menguji pesan yang diharapkan atau penyebab atau hal-hal lain yang berkaitan dengan pengecualian. Untuk memeriksa penyebab pengecualian, saya menggunakan: expectedException.expectCause (Mockito.sameInstance (expectedException)) atau expectedException.expectCause (Mockito.instanceOf (MyException.class)) dan beberapa lainnya yang berguna.
Crenguta S

19

Jawaban yang diperbarui untuk 06/19/2015 (jika Anda menggunakan java 8)

Cukup gunakan assertj

Menggunakan assertj-core-3.0.0 + Java 8 Lambdas

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

Referensi: http://blog.codeleak.pl/2015/04/junit-testing-exceptions-with-java-8.html


bekerja untuk saya ... Juga kita dapat memeriksa pesan pengecualian juga .assertThatThrownBy (() -> myService.sumTingWong ("badArg")). hasMessage ("test") .isInstanceOf (IllegalArgumentException.class);
Sritam Jagadev

17

Jika Anda menggunakan JUnit 4, dan Mockito 1.10.x anotasi metode pengujian Anda dengan:

@Test(expected = AnyException.class)

dan untuk membuang penggunaan pengecualian yang Anda inginkan:

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

16

Buat pengecualian terjadi seperti ini:

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

Verifikasi itu telah terjadi baik dengan menyatakan bahwa tes Anda akan mengeluarkan pengecualian seperti itu:

@Test(expected = AnException.class)

Atau dengan verifikasi tiruan normal:

verify(obj).someMethod();

Opsi terakhir diperlukan jika pengujian Anda dirancang untuk membuktikan kode perantara menangani pengecualian (yaitu pengecualian tidak akan dilempar dari metode pengujian Anda).


Apakah verifypanggilan tersebut menyatakan pengecualian?
NilsH

@NilsH Tidak. Tapi asalkan whenklausa itu benar, itu pasti telah melemparkan pengecualian.
Duncan Jones

10

Gunakan doTrow Mockito dan kemudian menangkap pengecualian yang diinginkan untuk menegaskan itu dibuang kemudian.

@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

Menggunakan mockito, Anda dapat membuat pengecualian terjadi.

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

Menggunakan Junit5, Anda dapat menyatakan pengecualian, menegaskan apakah yang eksepsi dilemparkan ketika metode pengujian dipanggil.

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

Temukan sampel di sini: sebutkan pengecualian junit


Terima kasih! Bekerja untuk saya
HariKishore

1

Tidak terkait dengan mockito, orang dapat menangkap pengecualian dan menegaskan propertinya. Untuk memverifikasi bahwa pengecualian itu benar-benar terjadi, nyatakan kondisi yang salah dalam blok coba setelah pernyataan yang melempar pengecualian.


Tanggapan @MariuszS dengan benar menjawab apa yang Anda katakan tidak terkait dengan Mockito
pringi

@ Pringi Terima kasih, saya melihat bahwa pertanyaan yang bersangkutan mengejek pengecualian dan menangkapnya. Saya bertanya-tanya apakah ini tergantung pada perilaku kode yang diuji.
belut ghEEz

1

Atau jika pengecualian Anda dilempar dari konstruktor kelas:

@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

Menegaskan dengan pesan pengecualian:

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

Jika ditulis seperti ini, ketika tidak ada pengecualian dilemparkan, tes akan tetap berlalu . Itulah yang ingin kita hindari sejak awal
Christian Lim
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.