[英]How to mock methods called by method under the test
我正在使用旧代码,并希望增加其测试范围。
我有一个像这样的课程:
public class MyStrategy implements SomeStrategy {
TimeAndDateUtils timeAndDateUtils = new TimeAndDateUtils();
@Override
public boolean shouldBeExtracted(Argument argument) {
Date currentDate = timeAndDateUtils.getCurrentDate();
return currentDate.isBefore(argument.getDate());
}
}
我想测试对timeAndDateUtils.getCurrentDate()
的调用来模拟shouldBeExtracted-Method,以便它返回一些固定值。
所以我想做的是:
Date currentDate = %some fixed date%
TimeAndDateUtils timeAndDateUtils = Mockito.mock(TimeAndDateUtils.class);
Mockito.when(timeAndDateUtils.getCurrentDate()).thenReturn(currentDate);
Assert.assertTrue(myStrategy.shouldBeExtracted(argument))
如何强制MyStrategy-Class使用模拟对象而不是创建它自己的对象?
您可以使用反射将模拟放入MyStrategy对象。 它看起来像这样:
MyStrategy myStrategy = new MyStrategy(); // I don't know if you are using DI
MyStrategy.class.getDeclaredField("timeAndDateUtils").set(myStrategy, timeAndDateUtilsMock);
假设您无法重写现有代码以使其更具可测试性,这是@InjectMocks
批注的典型用例, @InjectMocks
允许将模拟或间谍字段自动注入到测试对象中。
@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));
}
}
timeAndDateUtils
在类本身中创建了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);
Mockito有一个不错的类,用于覆盖类中的私有对象。 它称为WhiteBox。 它像这样工作
MyStrategy myStrategy = new MyStrategy();
TimeAndDateUtils timeAndDateUtils = Mockito.mock(TimeAndDateUtils.class);
Whitebox.setInternalState(myStartegy, "timeAndDateUtils", timeAndDateUtilsMock);
这将更改您的模拟的TimeAndDateUtils
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.