Mockito Come deridere e far valere un'eccezione generata?


Risposte:


75

Soluzione BDD Style (aggiornata a Java 8)

Mockito da solo non è la soluzione migliore per gestire le eccezioni, usa Mockito con Catch-Exception

Mockito + Catch-Exception + AssertJ

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

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

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

Codice di esempio

dipendenze


2
Che cos'è "catch-exception"? Hai un link?
Duncan Jones,

cosa caughtException?
Saif Masadeh

Capito, viene dacom.googlecode.catchexception.CatchException.caughtException;
Saif Masadeh,

212

Per rispondere prima alla tua seconda domanda. Se si utilizza JUnit 4, è possibile annotare il test con

@Test(expected=MyException.class)

per affermare che si è verificata un'eccezione. E per "deridere" un'eccezione con mockito, usa

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

2
questo approccio è inaccettabile nel caso in cui si stia testando il metodo di un oggetto con un certo stato. Ad esempio, esiste un metodo oggetto che genera un'eccezione se la si chiama la seconda volta. E devi testare per provare che genera un'eccezione durante la seconda chiamata del metodo, non la prima. Se genera MyException durante la prima chiamata del metodo (nella fase di preparazione), non dovrebbe superare il test. Ma con questo approccio non siamo in grado di verificare durante quale chiamata di metodo viene generata l'eccezione.
Sneg,

Anche se in questo caso possiamo prendere l'eccezione dalla prima chiamata del metodo e racchiuderla in RuntimeException.
Sneg,

29

Se si desidera testare anche il messaggio di eccezione, è possibile utilizzare ExpectedException di JUnit con 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()da dove viene?
Mohammad Faisal,


Preferisco anche usare @Rule, perché in questo modo posso verificare il messaggio o la causa previsti o altre cose relative all'eccezione. Per verificare la causa dell'eccezione, ne uso: expectedException.expectCause (Mockito.sameInstance (expectedException)) o expectedException.expectCause (Mockito.instanceOf (MyException.class)) e alcuni altri utili.
Crenguta S,

19

Risposta aggiornata per 19/06/2015 (se stai usando Java 8)

Usa assertj

Utilizzo di assertj-core-3.0.0 + Java 8 Lambdas

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

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


ha funzionato per me ... Inoltre possiamo controllare anche il messaggio di eccezione.assertThatThrownBy (() -> myService.sumTingWong ("badArg")). hasMessage ("test") .isInstanceOf (IllegalArgumentException.class);
Sritam Jagadev,

17

Se stai usando JUnit 4 e Mockito 1.10.x Annota il tuo metodo di test con:

@Test(expected = AnyException.class)

e per generare l'eccezione desiderata usare:

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

16

Fai in modo che l'eccezione accada in questo modo:

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

Verifica che sia successo affermando che il tuo test genererà tale eccezione:

@Test(expected = AnException.class)

O dalla normale verifica fittizia:

verify(obj).someMethod();

Quest'ultima opzione è necessaria se il test è progettato per dimostrare che il codice intermedio gestisce l'eccezione (ovvero l'eccezione non verrà generata dal metodo di test).


La verifychiamata afferma l'eccezione?
NilsH,

@NilsH No. Ma purché la whenclausola sia corretta, deve aver generato un'eccezione.
Duncan Jones,

10

Usa il doThrow di Mockito e poi cattura l'eccezione desiderata per affermare che è stata lanciata in seguito.

@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

Usando mockito, puoi far accadere l'eccezione.

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

Usando Junit5, puoi affermare un'eccezione, affermare se tale eccezione viene generata quando viene invocato il metodo di test .

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

Trova un esempio qui: asserisci eccezione junit


Grazie ! Ha funzionato per me
HariKishore il

1

Non correlato al mockito, si può catturare l'eccezione e affermarne le proprietà. Per verificare che si sia verificata l'eccezione, asserire una condizione falsa all'interno del blocco try dopo l'istruzione che genera l'eccezione.


La risposta di @MariuszS risponde correttamente a ciò che stai dicendo non è correlato a Mockito
pringi

@pringi Grazie, vedo che la domanda riguardava sia la derisione di un'eccezione che la cattura. Mi chiedo però se questo dipende da qualsiasi comportamento del codice in prova.
Eel GhEEz,

1

O se la tua eccezione viene generata dal costruttore di una classe:

@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

Asserire tramite messaggio di eccezione:

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

Se scritto in questo modo, quando non viene generata alcuna eccezione, il test continuerà comunque . Il che è ciò che vogliamo evitare in primo luogo
Christian Lim,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.