ユニットテストされているオブジェクトをスパイするのはコードのにおいですか?たとえば、文字列内の行数を単純に数えることがジョブのクラスLineCounter
を持っているとします。 -ユニットテストされているオブジェクト上のMockitoスパイリング
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
}
}
今私は、この高価なgetStringMetadata
呼び出しをあざけるながらgetNumLines
メソッドをテストするためのJUnit 4のテストを書きたいです。私はgetStringMetadata
にダミー値を返すようにMockitoのスパイメカニズムを使うことに決めました。
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");
}
}
これは妥当なことですか?実際のクラスではなくスパイオブジェクトをテストするのはとても奇妙だと思っていますが、実際にはそれに反対する理由は考えられません。
コードの改善をテストする場合があります。これは、文字列メタデータを取得する作業が別のクラスに抽出されるべきであるように見えます。このクラスは、 'LineCounter'によって委譲されます。その時点で、あなたは "継ぎ目"を作り、より一般的な(そしてより臭いのない)方法でその依存関係を模倣することができます – millhouse
@millhouseうん、それはそれを行う*正しい*方法のように見えることに全く賛成します。私は疑問に思っています、テストされているオブジェクトがスパイである私の例では本質的に何かが間違っていますか? – Matthew