【发布时间】:2016-08-12 09:23:50
【问题描述】:
我需要测试一些在方法调用中使用单例的遗留代码。测试的目的是确保类 sunder 测试调用单例方法。 我在 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'.
【问题讨论】:
-
你不能在 Mockito 中做到这一点,除非你重构你的类之一,而不使用 PowerMock。但我不确定你为什么要这样做。您正在对一种方法进行单元测试,只有一行,没有内部逻辑。这不能失败。将您的测试工作花在其他地方。
-
"测试的目的是确保类 sunder 测试调用单例方法。"任何好的测试用例都不应该以这种事情为目的。相反,旨在测试一些有意义的业务功能。模拟一个依赖并验证一个方法是否被调用不一定是错误的,但应该只在需要的时候做。
-
所有这些方法只会让人头疼......它们适用于静态方法,但如果它是实例的方法并且它引用一个类变量,它会得到空指针对吗?但 powerMockito 是一种方式。取而代之的是做我们在过去所做的事情,让我们的 singleTon 实现一个接口。然后在您的测试中使用其中包含所有存根的接口。参考:stackoverflow.com/a/17325647/835883
-
@fbielejec mock 方法里面是什么?
标签: java unit-testing junit mocking mockito