web-dev-qa-db-fra.com

Exception Mockito dans DoThrow qui semble correcte

J'essaie de me moquer d'une méthode pour voir si je gère correctement une exception. Ceci est aussi loin que je reçois.

interface:

interface SampleManager {
    void deleteVariome(String specimenId, String analysisId) throws Exception;
    // ...
}

test de l'unité:

// ...
SampleManger sampleManager = mock(SampleManager.class);

// below is line 753
doThrow(Exception.class).when(sampleManager).deleteVariome(sample1.getId(), analysisId);

résultat:

org.mockito.exceptions.misusing.UnfinishedStubbingException: 
Unfinished stubbing detected here:
-> at ...server.ArchiveManagerImplUTest.deleteVariomeFails(ArchiveManagerImplUTest.Java:753)

E.g. thenReturn() may be missing.
Examples of correct stubbing:
    when(mock.isOk()).thenReturn(true);
    when(mock.isOk()).thenThrow(exception);
    doThrow(exception).when(mock).someVoidMethod(); <-- this looks a log like what I did!

Hints:

 1. missing thenReturn()

 2. you are trying to stub a final method, you naughty developer! <-- I have a lot of other mocks of this interface in this test that work.
18
Karl K

D'après un problème identique que je viens de rencontrer, je soupçonne que sample est une maquette, et que vous ayez modifié sample.getId() ailleurs? Cela a causé ce problème dans mon cas, de toute façon.

Pour une raison quelconque, Mockito se fâche si l'un des arguments que vous transmettez au stub utilisé avec doThrow est le résultat d'une méthode que vous avez également moquée. Peut-être que c'est une vérification de ré-entrée pour éviter des boucles infinies, je ne sais pas.

Quoi qu’il en soit, essayez de remplacer sample.getId() par une valeur constante, ce qui devrait résoudre le problème. Vous pouvez envisager d'utiliser une constante déclarée dans votre test pour le modèle et toutes les utilisations ultérieures. Vous pouvez également vérifier que sample.getId() a été utilisé par la méthode que vous testez en ajoutant un autre appel à verify.

19
Gijs

Comme décrit dans la réponse de Gijs, cela est probablement dû à un bug dans Mockito. Voici un test complet qui le reproduit:

interface Sample { String getId(); }
interface SampleManager {
    void deleteVariome(String specimenId, String analysisId);
}

@Test
public void probableMockitoBug() {
    Sample sample1 = mock(Sample.class);
    when(sample1.getId()).thenReturn("a");

    SampleManager manager = mock(SampleManager.class);
    doThrow(Exception.class).when(manager).deleteVariome(sample1.getId(), "b");

    manager.deleteVariome("a", "b");
}

Le test produit la sortie suivante:

 org.mockito.exceptions.misusing.UnfinishedStubbingException: 
 Un stubbing inachevé a été détecté ici: 
-> à org.mockitousage.JavadocExamplesTest.probableMockitoBug (JavadocExamplesTest.Java:404) .____. thenReturn () peut être manquant .
 Exemples de stubbing correct: 
 quand (mock. isOk ()). thenReturn (true); 
 quand (mock.isOk ()). thenThrow (exception); 
 doThrow (exception) .when (mock) .someVoidMethod (); 
 Conseils: 
 1. manquant thenReturn () 
 2. vous essayez de stub une dernière méthode, développeur coquin! 

 à org.mockito.exceptions.Reporter.unfinishedStubbing (Reporter.Java:55) 
 à org.mockito.internal.progress.MockingProgressImpl.validateState (MockingProgressImpl.Java:74) 
 à org.mockito.internal.progress.ThreadSafeMockingProgress.validateState (ThreadSafeMockingProgress.Java:49) 
 à org.mockito.internal.MockHandler.handle (MockHandler.Java:71) 
 à org.mockito.internal.InvocationNotifierHandler.handle (InvocationNotifierHandler.Java:36) 
 à org.mockito.internal.creation.MethodInterceptorFilter.intercept (MethodInterceptorFilter.Java:48) 
 at org.mockitousage.JavadocExamplesTest $ Sample $$ EnhancerByMockitoWithCGLIB $$ d5ac41.getId () 
 à org.mockitousage.JavadocExamplesTest.probableMockitoBug (JavadocExamplesTest.Java:404) 
 à Sun.reflect.NativeMethodAccessorImpl.invoke0 (Méthode native) 
 à org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run (JUnit45AndHigherRunnerImpl.Java:37) 
 à org.mockito.runners.MockitoJUnitRunner.run (MockitoJUnitRunner.Java:62) 
4
Rogério

Cette erreur est généralement signalée APRÈS l'endroit où elle s'est réellement produite. Si vous ne parvenez pas à stub quelque chose correctement, Mockito ne peut généralement pas le savoir jusqu'à la prochaine fois que vous appelez l'une des méthodes Mockito. Cela peut être dans la même méthode de test, une méthode de test ultérieure dans la même classe ou même une classe de test totalement différente.

La ligne que vous avez citée me convient bien. Jetez un coup d’œil sur les lignes au-dessus, où vous appelez une méthode de stiff ou de vérification Mockito. Il est très probable que vous ayez un when auquel aucun thenReturn, then ou thenThrow ne soit associé. Ou vous pourriez avoir une verify qui manque l'appel de méthode réel. Il y a aussi quelques autres possibilités.

Si vous ne trouvez pas d'erreur dans les lignes AU-DESSUS de celle que vous avez citée, postez un peu plus de votre code et je regarderai de plus près.

4
Dawood ibn Kareem

vous devez fournir un instance de la classe Exception.class et non la classe Exception elle-même.

doThrow(new Exception()).when(sampleManager).deleteVariome(sample1.getId(), analysisId);

EDIT Bien @DavidWallace m'a corrigé, alors soyez averti (ou plutôt éclairé) que depuis 1.9 vous pouvez simplement fournir la classe d'exception à lancer et elle en construira une pour vous. 

0
Kevin Welker

Dans mon cas au lieu de 

doThrow(exception).when(mock).someVoidMethod()

était

doThrow(exception).when(mock.someVoidMethod())
0
CoolMind