2012-09-14 3 views
10

Sto scrivendo i test delle unità per la mia applicazione e mi chiedevo se è possibile che il framework Mockito influenzi un oggetto che viene passato in un metodo che restituisce il vuoto di una classe derisa . Ad esempio, chiamando una classe di convalida falsata che contiene un metodo che restituisce void ma tiene traccia di varie modifiche e metadati tramite un oggetto passato come argomento. .Come simulare un metodo di ritorno vuoto che interessa un oggetto

public GetCartItemsOutput getCartItems(GetCartItemsInput getCartItemsInput) { 
    CartItemsFilter cartItemsFilter = new CartItemsFilter(); 
    validator.validateCartItemsInput(getCartItemsInput, cartItemsFilter); ... 

ho deriso la classe di convalida per i miei altri test, ma per questo ho bisogno di prendere in giro le modifiche all'oggetto cartItemsFilter che io non so come fare.

risposta

18

La risposta è sì, è possibile, e ci sono fondamentalmente due livelli di fare questo, in base alla necessità del test.

Se si desidera semplicemente verificare l'interazione con l'oggetto deriso, è sufficiente utilizzare il metodo verify() per verificare che il metodo void sia stato chiamato.

Se il test ha bisogno veramente l'oggetto preso in giro per modificare i parametri passati ad esso, è necessario implementare un Answer:

A cura per mostrare la corretta forma di utilizzo risposta con il metodo vuoto

doAnswer(new Answer() { 
    Object answer(InvocationOnMock invocation) { 
     Object[] args = invocation.getArguments(); 
     ((MyClass)args[0]).myClassSetMyField(NEW_VALUE); 
     return null; // void method, so return null 
    } 
}).when(mock).someMethod(); 
+0

Grazie per il vostro aiuto. Mi ci è voluto un po 'per girare la testa "((MyClass) args [0]). MyClassSetMyField (NEW_VALUE);", ma alla fine ho capito che il punto era di impostare i parametri dell'argomento passato nel mio metodo deriso. Di nuovo, ty. – tamuren

0

ArgumentCaptor potrebbe anche aiutare.

Ecco un frammento trovato da here:

ArgumentCaptor<GetCartItemsInput > argument = ArgumentCaptor.forClass(GetCartItemsInput .class); 
    verify(mock).getCartItems(argument.capture()); 
    assertEquals(cartItemsFilter, argument.getValue()); 
+1

Questo non risolve il problema dell'op, ha bisogno di implementare una risposta – iwein

1

Per aggiungere alla risposta di Kevin Welker, se il MyClass è una classe personalizzata, quindi definire un metodo equals/codice hash in esso, in modo che Mockito può usarlo per abbinare esattamente al metodo call.

Nel mio caso, "MyClass" era in un'API di terze parti, quindi ho dovuto utilizzare il metodo "qualsiasi", come qui di seguito -

doAnswer(new Answer() { 
    Object answer(InvocationOnMock invocation) { 
     Object[] args = invocation.getArguments(); 
     ((MyClass)args[0]).myClassSetMyField(NEW_VALUE); 
     return null; // void method, so return null 
    } 
}).when(mock).someMethod(any(MyClass.class));