监视正在接受单元测试的对象是否有代码味道?例如,假设我有一个 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 的 spy 机制让 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 对象而不是实际类很奇怪,但我真的想不出反对它的理由。
最佳答案
我将分两部分回答这个问题。首先,是的,模拟或监视被测类是代码味道。这并不意味着它不能正确完成,而是它存在风险,应尽可能避免。
WRT 你的具体例子,我会看到如何正确使用 spy ,但这将基于你在其他地方已经完全单元测试 getStringMetadata
的断言。这就引出了一个问题,如果您在其他地方对 getStringMetadata
进行了完整的单元测试,那么您必须知道如何测试它,因此为什么不在没有 spy 的情况下测试 getNumLines
。
综上所述,millhouse
提出了一个很好的观点,但无论哪种方式,您都必须在某处对昂贵的代码进行单元测试。他的建议对帮助隔离昂贵的代码并确保您只需测试/运行一次有很大帮助。
关于java - Mockito 监视被单元测试的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19261014/