Ist es ein Code-Geruch, um ein Objekt, das getestet wird, auszuspionieren? Zum Beispiel habe ich eine Klasse LineCounter
, deren Aufgabe es ist, einfach die Anzahl der Zeilen in einer Zeichenfolge zu zählen. -Mockito Spy'ing auf dem zu testenden Objekt
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
}
}
Jetzt mag ich einen JUnit 4 Test schreiben, für diese die getNumLines
Methode zu testen, während des teueren getStringMetadata
Anruf spöttisch aus. Ich beschließe, Mockitos Spionage-Mechanismus zu verwenden, um getStringMetadata
einen Dummy-Wert zurückzugeben.
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");
}
}
Ist das eine vernünftige Sache zu tun? Ich fühle mich ziemlich komisch beim Testen eines Spy-Objekts anstatt der eigentlichen Klasse, aber ich kann mir nicht wirklich einen Grund dafür vorstellen.
Dies könnte ein Testfall sein, der zu einer Verbesserung Ihres Codes führt. Es sieht so aus, als ob die Aufgabe, String-Metadaten zu erhalten, in eine andere Klasse extrahiert werden sollte, an die dann 'LineCounter' delegiert wird. An diesem Punkt haben Sie eine "Naht" erstellt und können diese Abhängigkeit auf eine konventionellere (und weniger stinkende) Weise verspotten. – millhouse
@millhouse Ja, ich stimme völlig zu, dass dieser Weg wie der richtige Weg aussieht. Ich frage mich jedoch, gibt es irgendetwas an sich falsch mit meinem Beispiel, wo das zu testende Objekt ein Spion ist? – Matthew