Je souhaite vérifier le comportement de la méthode suivante
public void methodToTest( Exception e, ActionErrors errors ) {
...
errors.add( "exception.message",
ActionMessageFactory.createErrorMessage(e.toString() ));
errors.add( "exception.detail",
ActionMessageFactory.createErrorMessage(e.getStackTrace()[0].toString() ));
...
}
Dans ma classe @Test, j'espérais faire quelque chose comme ceci pour vérifier que errors.add()
est appelé avec "exception.message" et à nouveau avec "exception.detail".
verify(errors).add(eq("exception.message"), any(ActionError.class));
verify(errors).add(eq("exception.detail"), any(ActionError.class));
cependant Mockito se plaint comme suit
Argument(s) are different! Wanted:
actionErrors.add(
"exception.message",
<any>
);
Actual invocation has different arguments:
actionErrors.add(
"exception.detail",
org.Apache.struts.action.ActionError@38063806
);
Comment puis-je dire à Mockito de vérifier les deux valeurs?
Des lectures supplémentaires m'ont amené à essayer d'utiliser ArgumentCaptors et les travaux suivants, bien que beaucoup plus verbeux que je le voudrais.
ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);
verify(errors, atLeastOnce()).add(argument.capture(), any(ActionMessage.class));
List<String> values = argument.getAllValues();
assertTrue(values.contains("exception.message"));
assertTrue(values.contains("exception.detail"));
Si l'ordre des deux appels add()
est pertinent, vous pouvez utiliser InOrder
:
InOrder inOrder = inOrder(errors, errors);
inOrder.verify(errors).add(eq("exception.message"), any(ActionError.class));
inOrder.verify(errors).add(eq("exception.detail"), any(ActionError.class));
Essayez quelque chose comme ça:
verify(errors, times(2))
.add(AdditionalMatchers.or(eq("exception.message"), eq("exception.detail")),
any(ActionError.class));
vous avez probablement un problème dans votre code. En fait, vous écrivez ce code:
Map<Character, String> map = mock(Map.class);
map.put('a', "a");
map.put('b', "b");
map.put('c', "c");
verify(map).put(eq('c'), anyString());
verify(map).put(eq('a'), anyString());
verify(map).put(eq('b'), anyString());
Notez que la première vérification n'est même pas en ordre en ce qui concerne les invocations réelles.
De plus, je vous recommanderais de ne pas vous moquer de types que vous ne possédez pas, par exemple le type struts.
[EDIT @Brad]
Après avoir exécuté le code de Brice (ci-dessus) dans mon IDE), je constate que j'ai utilisé ActionError au lieu d'ActionMessage, c'est pourquoi ma verify () ne correspondait pas. me trompant en me faisant croire que c’était le premier argument qui ne correspondait pas.
Donc, la réponse à ma question est
/**
* note that ActionMessageFactory.createErrorMessage() returns ActionMessage
* and ActionError extends ActionMessage
*/
verify(errors).add(eq("exception.message"), any(ActionMessage.class));
verify(errors).add(eq("exception.detail"), any(ActionMessage.class));
Vous pouvez utiliser Mockito.atLeastOnce()
qui permet à Mockito de réussir le test même si cet objet mockObject sera appelé plusieurs fois.
Mockito.verify(mockObject, Mockito.atLeastOnce()).testMethod(Mockito.eq(1));
Mockito.verify(mockObject, Mockito.atLeastOnce()).testMethod(Mockito.eq(2));
De manière similaire à @ sendon1928, nous pouvons utiliser:
Mockito.times(wantedInvocationCount)
pour être sûr que la méthode s'appelle le nombre exact de fois (solution préférable à mon avis). Ensuite, nous pouvons appeler
Mockito.verifyNoMoreInteractions(mock)
Pour s'assurer que cette maquette n'était plus utilisée dans aucun contexte. Exemple complet:
Mockito.verify(mockObject, Mockito.times(wantedInvocationCount)).testMethod(Mockito.eq(1));
Mockito.verify(mockObject, Mockito.times(wantedInvocationCount)).testMethod(Mockito.eq(2));
Mockito.verifyNoMoreInteractions(mockObject)