studio programacion móviles libro desarrollo curso aplicaciones java mockito

java - móviles - manual de programacion android pdf



Cómo verificar múltiples llamadas a métodos con diferentes parámetros. (5)

Tengo el siguiente método que deseo verificar el comportamiento en

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

En mi clase @Test esperaba hacer algo como esto para verificar que se llama a errors.add() con "exception.message" y nuevamente con "exception.detail"

verify(errors).add(eq("exception.message"), any(ActionError.class)); verify(errors).add(eq("exception.detail"), any(ActionError.class));

sin embargo Mockito se queja de la siguiente manera

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 );

¿Cómo puedo decirle a Mockito que compruebe ambos valores?


Intenta algo como esto:

verify(errors, times(2)) .add(AdditionalMatchers.or(eq("exception.message"), eq("exception.detail")), any(ActionError.class));


Lecturas adicionales me han llevado a intentar usar ArgumentCaptors y los siguientes trabajos, aunque mucho más detallados de lo que me gustaría.

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"));


Probablemente tienes un problema en tu código. Porque de hecho realmente escribes este código:

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

Tenga en cuenta que la primera verificación ni siquiera está en orden con respecto a las invocaciones reales.

Además, le recomiendo que no se burle de los tipos que no posee, por ejemplo, el tipo de puntal.

[EDITAR @Brad]

Después de ejecutar el código de Brice (arriba) en mi IDE, puedo ver que he usado ActionError en lugar de ActionMessage, por lo que mi verificación () no coincide. El mensaje de error que inicialmente publiqué me engañaba al pensar que era el primer argumento que no coincidía. Resulta que era el segundo argumento.

Así que la respuesta a mi pregunta es

/** * 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));


Puedes usar Mockito.atLeastOnce() que le permite a Mockito pasar la prueba, incluso si ese mockObject se llamará muchas veces.

Mockito.verify(mockObject, Mockito.atLeastOnce()).testMethod(Mockito.eq(1)); Mockito.verify(mockObject, Mockito.atLeastOnce()).testMethod(Mockito.eq(2));


Si el orden de las dos llamadas add() es relevante, puede usar 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));