我正在使用旧版代码,并希望增加其测试覆盖范围。
我有一个类似:
的课程public class MyStrategy implements SomeStrategy {
TimeAndDateUtils timeAndDateUtils = new TimeAndDateUtils();
@Override
public boolean shouldBeExtracted(Argument argument) {
Date currentDate = timeAndDateUtils.getCurrentDate();
return currentDate.isBefore(argument.getDate());
}
}
我想测试sysextracted方法的模拟呼叫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级使用模拟对象而不是创建其自己的对象?
您可以使用反射将模拟对象放入Mystrategy对象。看起来像这样:
MyStrategy myStrategy = new MyStrategy(); // I don't know if you are using DI
MyStrategy.class.getDeclaredField("timeAndDateUtils").set(myStrategy, timeAndDateUtilsMock);
假设您不能重写现有代码以使其更容易测试,这是注释@InjectMocks
的典型用例,允许 Injext Mock或Spy Fields in自动测试的对象。
@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));
}
}
Mockito有一个不错的类,用于覆盖类内部的私人对象。它称为白框。它像这样的工作
MyStrategy myStrategy = new MyStrategy();
TimeAndDateUtils timeAndDateUtils = Mockito.mock(TimeAndDateUtils.class);
Whitebox.setInternalState(myStartegy, "timeAndDateUtils", timeAndDateUtilsMock);
将更改您的Mock
timeAndDateUtils
是在类本身中创建的,这使得很难访问测试。通过构造函数注入依赖关系,以便可以创建模拟
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);