我正在使用遗留代码,并希望增加它的测试覆盖率。
我有一个类:
public class MyStrategy implements SomeStrategy {
TimeAndDateUtils timeAndDateUtils = new TimeAndDateUtils();
@Override
public boolean shouldBeExtracted(Argument argument) {
Date currentDate = timeAndDateUtils.getCurrentDate();
return currentDate.isBefore(argument.getDate());
}
}
我想测试一下shouldBeExtracted-Method模拟对timeAndDateUtils.getCurrentDate()
的调用,以便它返回一些固定值。
所以我要做的是:
Date currentDate = %some fixed date%
TimeAndDateUtils timeAndDateUtils = Mockito.mock(TimeAndDateUtils.class);
Mockito.when(timeAndDateUtils.getCurrentDate()).thenReturn(currentDate);
Assert.assertTrue(myStrategy.shouldBeExtracted(argument))
如何强制MyStrategy-Class使用模拟对象而不是创建自己的对象?
答案 0 :(得分:1)
您可以使用反射将mock放入MyStrategy对象中。它看起来像这样:
MyStrategy myStrategy = new MyStrategy(); // I don't know if you are using DI
MyStrategy.class.getDeclaredField("timeAndDateUtils").set(myStrategy, timeAndDateUtilsMock);
答案 1 :(得分:1)
假设您无法重写现有代码以使其更易于测试,这是注释@InjectMocks
的典型用例,允许将mock或spy字段自动注入测试对象。
@RunWith(MockitoJUnitRunner.class)
public class MyStrategyTest {
@Mock
private TimeAndDateUtils timeAndDateUtils;
@InjectMocks
private MyStrategy myStrategy;
@Test
public void testShouldBeExtracted() {
...
Mockito.when(timeAndDateUtils.getCurrentDate()).thenReturn(currentDate);
Assert.assertTrue(myStrategy.shouldBeExtracted(argument));
}
}
答案 2 :(得分:0)
public class MyStrategy implements SomeStrategy {
TimeAndDateUtils timeAndDateUtils;
public MyStrategy(TimeAndDateUtils timeAndDateUtils) {
this.timeAndDateUtils = timeAndDateUtils;
}
@Override
public boolean shouldBeExtracted(Argument argument) {
Date currentDate = timeAndDateUtils.getCurrentDate();
return currentDate.isBefore(argument.getDate());
}
}
,这使得访问测试变得困难。通过构造函数注入依赖项,以便可以创建模拟
//Arrange
Date currentDate = %some fixed date%
TimeAndDateUtils timeAndDateUtils = Mockito.mock(TimeAndDateUtils.class);
Mockito.when(timeAndDateUtils.getCurrentDate()).thenReturn(currentDate);
MyStrategy myStrategy = new MyStrategy(timeAndDateUtils);
//Act
bool result = myStrategy.shouldBeExtracted(argument);
//Assert
Assert.assertTrue(result);
测试
{{1}}
答案 3 :(得分:0)
Mockito有一个很好的类来覆盖类中的私有对象。它被称为WhiteBox。它像这样工作
MyStrategy myStrategy = new MyStrategy();
TimeAndDateUtils timeAndDateUtils = Mockito.mock(TimeAndDateUtils.class);
Whitebox.setInternalState(myStartegy, "timeAndDateUtils", timeAndDateUtilsMock);
这会改变你的模拟的TimeAndDateUtils