Mat*_*att 13 java junit unit-testing mockito
间谍对正在进行单元测试的物体是否有代码味?例如,假设我有一个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
}
}
Run Code Online (Sandbox Code Playgroud)
现在我想为此编写一个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");
}
}
Run Code Online (Sandbox Code Playgroud)
这是合理的事吗?我觉得测试一个Spy对象而不是实际的类很奇怪,但是我无法想到反对它的原因.
我分两部分回答这个问题。首先,是的,模拟或监视被测类是代码味道。这并不意味着它不能正确完成,而是意味着它容易产生风险,应尽可能避免。
关于您的具体示例,我将了解如何正确使用间谍,但这将基于您在其他地方进行了全面单元测试的断言getStringMetadata
。这就引出了一个问题,如果您getStringMetadata
在其他地方进行了全面的单元测试,那么您必须知道如何测试它,因此为什么getNumLines
不在没有间谍的情况下进行测试。
话虽这么说,millhouse
但无论哪种方式,你都必须在某个地方对昂贵的代码进行单元测试。他的建议对于帮助隔离昂贵的代码并确保您只需测试/练习一次有很大帮助。
归档时间: |
|
查看次数: |
5917 次 |
最近记录: |