2011-12-14 24 views
55

tengo el siguiente método que deseo para verificar el comportamiento deCómo verificar varias llamadas a métodos con diferentes parametros

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 Tenía la esperanza de hacer algo como esto para verificar que se llama errors.add() con "Exception.Message" y de nuevo con "exception.detail"

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

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", 
    [email protected] 
); 

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

+0

Cuando tiene 2 métodos con firma diferente, puede escribir un caso de prueba por separado para ambos. –

+1

Sí, pero en este caso es la misma firma de método pero solo diferentes valores de argumento – Brad

Respuesta

55

Otras lecturas me ha llevado a tratar de usar ArgumentCaptors y las siguientes obras, aunque mucho más detallado 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")); 
17

intentar algo como esto:

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

es probable que tenga un problema en el código. Porque, como cuestión de hecho en realidad se escribe 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()); 

Nota el primer verificar ni siquiera está en orden en lo que se refiere a las invocaciones reales.

Además, le recomendaría que no se burle de los tipos que no le pertenecen, por ejemplo, el tipo de puntales.

[EDIT @Brad]

Después de ejecutar código de Brice (arriba) en mi IDE puedo ver que he utilizado en lugar de ActionError ActionMessage, así que por eso mi verificar() no se pongan en venta. El mensaje de error que inicialmente publiqué me indujo a error al pensar que era el primer argumento que no coincidía. Resulta que fue 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)); 
+0

No entienda lo que está tratando de decir. ¿Es importante el orden de verificación? si el orden de verificación es importante. ¿Por qué entonces aquí se proporciona la API de InOrder? –

+0

Al igual que lo que está escrito anteriormente, el orden de verificación es irrelevante; es por eso que hay 'InOrder'. – Brice

31

Si el orden de los dos add() llamadas es relevante, puede utilizar 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)); 
+0

Esta es la respuesta correcta y moderna. – Lambart

+1

Basta con pasar el argumento de 'errores' único: ' InOrder inOrder = inOrder (errors); '(ver [docs] (http://javadoc.io/page/org.mockito/mockito-core/latest/org) /mockito/Mockito.html#in_order_verification)) – GreenhouseVeg

3

Usted puede utilizar Mockito.atLeastOnce() que permite Mockito para pasar la prueba, incluso si eso mockObject será llamado muchas veces.

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

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