È un odore di codice per spiare un oggetto sottoposto a test dell'unità? Ad esempio, supponiamo di avere una classe LineCounter
il cui compito è semplicemente contare il numero di righe in una stringa. -Mockito Spy'ing sull'oggetto sottoposto a test di unità
class LineCounter {
public int getNumLines(String string) {
String metadata = getStringMetadata(string);
// count lines in file
return numLines;
}
/** Expensive operation */
protected String getStringMetadata(String string) {
// do stuff with string
}
}
Ora voglio scrivere un test JUnit 4 per questo per testare il metodo getNumLines
mentre beffardo il costoso getStringMetadata
chiamata. Decido di utilizzare il meccanismo di spionaggio di Mockito per fare in modo che getStringMetadata
restituisca un valore fittizio.
class LineCounterTests {
@Test public void testGetNumLines() {
LineCounter lineCounterSpy = Mockito.spy(new LineCounter());
// Mock out expensive call to return dummy value.
Mockito.when(lineCounterSpy.getStringMetadata(Mockito.anyString()).thenReturn("foo");
assertEquals(2, lineCounterSpy.getNumLines("hello\nworld");
}
}
È una cosa ragionevole da fare? Mi sento piuttosto strano testare un oggetto Spy piuttosto che la classe reale, ma non riesco davvero a pensare a un motivo contrario.
Questo potrebbe essere un caso di test che guida un miglioramento del codice. Sembra che il compito di ottenere i metadati della stringa debba essere estratto in un'altra classe, a cui viene poi demandato 'LineCounter'. A quel punto hai creato una "cucitura" e puoi deridere quella dipendenza in un modo più convenzionale (e meno puzzolente) – millhouse
@millhouse Sì, sono assolutamente d'accordo che quel modo sembra il modo * giusto * per farlo. Mi chiedo però, c'è qualcosa di intrinsecamente sbagliato nel mio esempio in cui l'oggetto testato è una spia? – Matthew