【发布时间】:2013-10-16 03:52:59
【问题描述】:
监视正在单元测试的对象是否是代码异味?例如,假设我有一个 LineCounter 类,其工作是简单地计算字符串中的行数。 --
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
}
}
现在我想为此编写一个 JUnit 4 测试来测试 getNumLines 方法,同时模拟昂贵的 getStringMetadata 调用。我决定使用 Mockito 的间谍机制让 getStringMetadata 返回一个虚拟值。
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");
}
}
这是合理的做法吗?我觉得测试一个 Spy 对象而不是实际的类很奇怪,但我真的想不出反对它的理由。
【问题讨论】:
-
这可能是一个测试驱动改进代码的案例。看起来获取字符串元数据的工作应该被提取到另一个类,然后由
LineCounter委托给另一个类。此时,您已经创建了一个“接缝”,并且可以以更传统(且不那么臭)的方式模拟这种依赖关系 -
@millhouse 是的,完全同意这种方式确实是正确的方式。不过,我想知道,在我的示例中,被测试的对象是间谍,有什么本质上的错误吗?
标签: java unit-testing junit mockito