繁体   English   中英

如何模拟被测试方法调用的方法

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM