2010-11-15 7 views
19

Supponiamo che un frammento di codice di prova:C'è un modo per avere qualcosa come l'argomento jUnit Assert nel metodo di verifica di Mockito?

Observable model = Class.forName(fullyQualifiedMethodName).newInstance(); 
Observer view = Mockito.mock(Observer.class); 
model.addObserver(view); 
for (Method method : Class.forName(fullyQualifiedMethodName).getDeclaredMethods()) 
{ 
    method.invoke(model, composeParams(method)); 
    model.notifyObservers(); 
    Mockito.verify(
    view, Mockito.atLeastOnce() 
).update(Mockito.<Observable>any(), Mockito.<Object>any()); 
} 

Mockito.verify metodo genera un'eccezione se un metodo in un modello non ha invocato Observable.setChanged() metodo.

Problema: senza aggiungere loggers/System.print.out Non riesco a capire quale sia il metodo corrente che ha fallito il test. Esiste un modo di avere qualcosa di simile a jUnit Assert metodi:

Assert.assertEquals(
    String.format("instances %s, %s should be equal", inst1, inst2), 
    inst1.getParam(), 
    inst2.getParam() 
); 

SOLUZIONE:

verify(observer, new VerificationMode() 
{ 
    @Override 
    public void verify(VerificationData data) 
    { 
    assertTrue(
     format(
      "method %s doesn't call Observable#setChanged() after changing the state of the model", 
      method.toString() 
     ), 
     data.getAllInvocations().size() > 0); 
    } 
}).update(Mockito.<Observable>any(), Mockito.<Object>any()); 

risposta

17

Questo fa il trucco (semplice e chiara):

try { 
verify(myMockedObject, times(1)).doSomthing(); 
} catch (MockitoAssertionError e) { 
    throw new MockitoAssertionError("Was expecting a call to myMockedObject.doSomthing but got "+ e.getMessage()); 
} 
+6

Passare la causa come seconda argomentazione è solitamente meglio che concatenare il messaggio. 'lancio nuovo MockitoAssertionError (" message ", e)' – Kapep

+1

MockitoAssertionError non ha un costruttore con i parametri MockitoAssertionError (String, Exception) Io uso 'new AssertionError (" message ", exception)' poichè questo è il tipo di eccezione che è lanciato da JUnit per le asserzioni. –

3

Non c'è una chiamata API diretta che consente a un messaggio per una verifica. Ma penso che se cambi la tua firma di verifica per usare l'oggetto metodo piuttosto che Mockito.any(), il toString() sulla classe Method eseguirà il kick in e ti darà quello che vuoi.

Qualcosa di simile.

import static org.mockito.Matchers.anyObject; 
import static org.mockito.Mockito.atLeastOnce; 
import static org.mockito.Mockito.verify; 
import static org.mockito.Matchers.eq; 

... 

Observable model = Class.forName("class name").newInstance(); 

verify(view, times(1)).update(eq(model), anyObject()); 

for (Method method : Class.forName("class name").getDeclaredMethods()) 
{ 
    method.invoke(model, composeParams(method)); 
    model.notifyObservers(); 
    verify(view, atLeastOnce()).update(eq(method), anyObject()); 
} 
+0

Bel tentativo, ma non è andare a lavorare. Il primo metodo dell'aggiornamento Observer # (Object source, Object arg) è il modello che sta trasmettendo la modifica, non il metodo che ha cambiato il suo stato. –

+0

Basta aggiungere l'aspettativa che si desidera vedere. Se questo include un altro tipo di osservabile, così sia. –

+0

Probabilmente è necessario aggiungere altro codice che spieghi meglio la struttura della classe. –

1

È possibile creare un matcher per stampare informazioni sul metodo corrente. Sarà un po 'goffo, ma funzionerà stampando il nome del metodo quando la verifica fallisce.

6

Non si può fare in mockito. La sintassi di Mockito rende molto facile testare il comportamento previsto, ma non ha alcun concetto di stato del test.

Quello che stai cercando di fare è avere alcune informazioni che non sono nell'oggetto beffeggiato quando le mock falliscono le aspettative.

Se si vuole veramente fare, vedo 2 modi generali: o si crea il proprio verificationMode implementando l'interfaccia

org.mockito.verification; 
public static interface VerificationMode 

e l'aggiunta di un metodo come atLeastOnceMsd (String msg) che mostrerà il messaggio in caso di errore o aggiunta del metodo testato corrente nel modello all'oggetto della vista

per esempio con una linea simile nel loop interno.

view.setName("now we are testing " + method.getName()); 
Problemi correlati