如何模拟测试中通过方法调用的方法



我正在使用旧版代码,并希望增加其测试覆盖范围。

我有一个类似:

的课程
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

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);

相关内容

  • 没有找到相关文章

最新更新