2011-12-14 14 views
55

ho il seguente metodo che desidero per verificare il comportamento sullaCome verificare il metodo più chiamate con diversi params

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

    ... 
} 

Nella mia classe @Test speravo di fare qualcosa di simile per verificare che si chiama errors.add() con "exception.message" e di nuovo con "exception.detail"

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

tuttavia Mockito lamenta come segue

Argument(s) are different! Wanted: 
actionErrors.add(
    "exception.message", 
    <any> 
); 

Actual invocation has different arguments: 
actionErrors.add(
    "exception.detail", 
    [email protected] 
); 

Come posso dire a Mockito di verificare entrambi i valori?

+0

quando si hanno 2 metodi con firma diversa, è possibile scrivere un test case separato per entrambi. –

+1

Sì, ma in questo caso è la stessa firma del metodo ma solo valori di argomento diversi – Brad

risposta

55

Ulteriore lettura mi ha portato a provare a utilizzare ArgumentCaptors e le seguenti opere, anche se molto più dettagliato di quanto vorrei.

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

provare qualcosa di simile:

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

probabilmente avete un problema nel codice. Perché, come un dato di fatto che effettivamente scrivere questo codice:

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 la prima verifica non è nemmeno in ordine nella materia delle invocazioni attuali.

Inoltre, ti consiglio di non creare in realtà tipi non di tua proprietà, ad esempio il tipo di puntoni.

[EDIT @Brad]

Dopo l'esecuzione di codice di Brice (sopra) nel mio IDE posso vedere che ho usato al posto del ActionError ActionMessage, così che è il motivo per cui la mia verificare() non è stato corrispondente. Il messaggio di errore che ho postato inizialmente mi induceva a pensare che fosse il primo argomento che non corrispondeva. Si scopre che era il secondo argomento.

Quindi la risposta alla mia domanda è

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

Non ottieni quello che stai cercando di dire. L'ordine di verifica è importante? se l'ordine di verifica è importante. Perché allora qui è fornito l'API di InOrder? –

+0

Proprio come ciò che è scritto sopra l'ordine di verifica è irrilevante; ecco perché c'è "InOrder". – Brice

31

Se l'ordine dei due add() chiamate è rilevante, è possibile utilizzare 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

Questa è la risposta corretta, moderna. – Lambart

+1

È sufficiente passare il singolo argomento 'errors': ' InOrder inOrder = inOrder (errori); '(consultare [docs] (http://javadoc.io/page/org.mockito/mockito-core/latest/org /mockito/Mockito.html#in_order_verification)) – GreenhouseVeg

3

È possibile utilizzare Mockito.atLeastOnce() che permette Mockito per superare la prova, anche se questo MockObject sarà chiamato molte volte.

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

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