Quindi mi è stato chiesto di leggere su beffe e BDD per il nostro team di sviluppo e di giocare con i mock in modo da migliorare una manciata dei nostri test unitari esistenti (come esperimento).Mockito: derisione "Blackbox" Dipendenze
Alla fine ho scelto di andare con Mockito per una serie di motivi (alcuni al di fuori della portata del mio controllo), ma in particolare perché supporta sia lo stubing che il mocking per le istanze in cui il mocking non sarebbe appropriato.
Ho passato tutto il giorno a studiare su Mockito, beffardo (in generale) e BDD. E ora sono pronto per scavare e iniziare ad aumentare i nostri test unitari.
Così abbiamo una classe denominata WebAdaptor
che ha un metodo run()
:
public class WebAdaptor {
private Subscriber subscriber;
public void run() {
subscriber = new Subscriber();
subscriber.init();
}
}
Si prega di notare: (! Per motivi al di fuori della portata di questa domanda) Non ho un modo per modificare questo codice . Così faccio non ho la possibilità di aggiungere un metodo setter per Subscriber
, e quindi può essere pensato come un "blackbox" irraggiungibile all'interno del mio WebAdaptor
.
Voglio scrivere uno unit test che incorpora un finto Mockito
, e lo utilizza per finta verify
che l'esecuzione WebAdaptor::run()
provoca Subscriber::init()
di essere chiamato.
Quindi, ecco quello che ho finora (all'interno WebAdaptorUnitTest
):
@Test
public void runShouldInvokeSubscriberInit() {
// Given
Subscriber mockSubscriber = mock(Subscriber.class);
WebAdaptor adaptor = new WebAdaptor();
// When
adaptor.run();
// Then
verify(mockSubscriber).init();
}
Quando ho eseguito questo test, il metodo effettivo Subscriber::init()
viene eseguito (vi posso dire dall'uscita della console e dei file vedendo generato sul mio sistema locale), non il mockSubscriber
, che non dovrebbe fare (o restituire) nulla.
Ho controllato e ricontrollato: init
è public
, non è né static
o final
, e restituisce void
. Secondo i documenti, Mockito non dovrebbe avere problemi a deridere questo oggetto.
Quindi mi ha fatto pensare: devo associare esplicitamente lo mockSubscriber
allo adaptor
? Se questo è un caso, allora di solito, quanto segue normalmente risolvere il problema:
adaptor.setSubscriber(mockSubscriber);
Ma dal momento che non posso aggiungere tale setter (si prega di leggere la mia nota di cui sopra), sono ad una perdita quanto a come avrei potuto forza una tale associazione. Quindi, diverse domande strettamente correlate:
- Qualcuno può confermare che ho impostato correttamente il test (utilizzando l'API Mockito)?
- Il mio sospetto riguardo al setter mancante è corretto? (Devo associare questi oggetti tramite un setter?)
- Se il mio sospetto sopra è vero, e non posso modificare
WebAdaptor
, ci sono delle circostanze a mia disposizione?
Grazie in anticipo!
Questo non risponde direttamente alla tua domanda, ma JMockit rende questo tipo di black-box beffardo abbastanza facile. JMockIt è un'opzione per te? –
In che modo il Sottoscrittore viene istanziato in questa classe? È possibile sovrascrivere il codice di istanziazione per restituire un'istanza che controlli? –
run() è l'unico metodo che utilizza il Sottoscrittore, quindi con tutti i mezzi dovrebbe essere una variabile locale all'interno di quel metodo. Ancora una volta, non posso modificare il codice ... – IAmYourFaja