我需要测试一些遗留代码,它在 aa 方法调用中使用单例。测试的目的是确保类拆分器测试调用单例方法。我在 SO 上看到过类似的问题,但所有答案都需要其他依赖项(不同的测试框架)——不幸的是,我仅限于使用 Mockito 和 JUnit,但使用这种流行的框架,这应该是完全可能的。
单身人士:
public class FormatterService {
private static FormatterService INSTANCE;
private FormatterService() {
}
public static FormatterService getInstance() {
if (INSTANCE == null) {
INSTANCE = new FormatterService();
}
return INSTANCE;
}
public String formatTachoIcon() {
return "URL";
}
}
被测类:
public class DriverSnapshotHandler {
public String getImageURL() {
return FormatterService.getInstance().formatTachoIcon();
}
}
单元测试:
public class TestDriverSnapshotHandler {
private FormatterService formatter;
@Before
public void setUp() {
formatter = mock(FormatterService.class);
when(FormatterService.getInstance()).thenReturn(formatter);
when(formatter.formatTachoIcon()).thenReturn("MockedURL");
}
@Test
public void testFormatterServiceIsCalled() {
DriverSnapshotHandler handler = new DriverSnapshotHandler();
handler.getImageURL();
verify(formatter, atLeastOnce()).formatTachoIcon();
}
}
这个想法是配置可怕的单例的预期行为,因为被测试的类将调用它的 getInstance 然后是 formatTachoIcon 方法。不幸的是,这失败并显示错误消息:
when() requires an argument which has to be 'a method call on a mock'.
原文由 fbielejec 发布,翻译遵循 CC BY-SA 4.0 许可协议
您所要求的是不可能的,因为您的遗留代码依赖于静态方法
getInstance()
并且 Mockito 不允许模拟静态方法,因此以下行将不起作用有两种方法可以解决此问题:
使用允许模拟静态方法的不同模拟工具,例如 PowerMock。
重构您的代码,以便您不依赖静态方法。我能想到的实现这一点的侵入性最小的方法是向
DriverSnapshotHandler
添加一个构造函数,它会注入FormatterService
依赖项。此构造函数将仅用于测试,您的生产代码将继续使用真正的单例实例。然后,您的测试应如下所示: