如何在测试

时间:2016-12-05 11:18:11

标签: java unit-testing mocking mockito

我正在使用遗留代码,并希望增加它的测试覆盖率。

我有一个类:

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使用模拟对象而不是创建自己的对象?

4 个答案:

答案 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