mockito 将使用动态值调用另一个函数的函数的单元测试

ewm0tg9j  于 2022-12-13  发布在  其他
关注(0)|答案(1)|浏览(161)

我正在尝试为函数rollDays编写测试,但遇到了NullPointerException。
如果我想测试的方法将调用另一个函数Closed,并且由于for循环for (int numOfDays = Math.abs(days); Closed(date, mar) || numOfDays-- > 0; date = date.plusDays((long) dir))而将采用各种动态值(日期),我不太确定应该如何处理该测试
我想测试的方法在一个名为CalculateDateService的类中:它被调用的地方是:
finalDate = rollDays(3, localDate, DateService.marID);
CalculateDateService内部的方法:
第一个
在测试中:

@Mock
private DateService dateService;

@InjectMocks
private CalculateDateService tested;

@Test
public void testRollDays() {
        LocalDate initDate = LocalDate.of(2022, 12, 22);
       
        //i suspect I have something wrong below 
        when(tested.Closed(initDate, dateService.marID)).thenReturn(Boolean.FALSE);
        when(dateService.today()).thenReturn(initDate);
        when(tested.NonSettle(initDate)).thenReturn(Boolean.FALSE);
        LocalDate rolledDate = tested.rollDays(4, initDate, DateService.marID);
        LocalDate correctRolledDate = LocalDate.of(2022, 12, 29);
        assertEquals(correctRolledDate, rolledDate);
}

我得到的错误是:
计算日期服务时出现空指针异常。
在计算日期服务。在计算日期关闭服务测试。testRollDays
任何帮助都将不胜感激。提前感谢。

yqlxgs2m

yqlxgs2m1#

由于tested既不是Mock也不是Spy,因此引发异常。
您可能想要尝试沿着以下的方法:

@Test
    void testSpyFalseRoll1201by24(){
        var year = LocalDate.now().getYear();
        var spy = Mockito.spy(new CalculateDateService());
        Mockito.doReturn(false).when(spy).nonSettle(Mockito.any(LocalDate.class));
        var result = spy.rollDays(24, LocalDate.of(year, 12, 1), "");
        Assert.assertEquals(result, LocalDate.of(year, 12, 25));
    }

    @Test
    void testSpyTrueOn1224Roll1201by24(){
        var year = LocalDate.now().getYear();
        var spy = Mockito.spy(new CalculateDateService());
        Mockito.doReturn(false).when(spy).nonSettle(Mockito.any(LocalDate.class));
        Mockito.doReturn(true).when(spy).nonSettle(LocalDate.of(year, 12, 24));
        var result = spy.rollDays(24, LocalDate.of(year, 12, 1), "");
        Assert.assertEquals(result, LocalDate.of(year, 12, 26));
    }

我在这里所做的是stubbing。这在你的情况下工作得很好,但你需要小心:
真实的的间谍应该小心地使用**,偶尔也会使用**,例如在处理遗留代码时。
Mockito文档“监视真实的对象”。
在这下面,文档写道:
Mockito不会委托对所传递的真实的示例的调用,而是实际创建它的副本。
请注意,我删除了DateService,只是因为它不是问题的一部分。下面是我对CalculateDateService的简化定义:

public class CalculateDateService {
    LocalDate rollDays(int days, LocalDate date, String mar) {
        int dir = days > 0 ? 1 : -1;
        for(int numOfDays = Math.abs(days); closed(date, mar) || numOfDays-- > 0; date = date.plusDays((long) dir)) {

        }
        return date;
    }

    Boolean closed(LocalDate date, String mar){
        return this.nonSettle(date);
    }

    Boolean nonSettle(LocalDate date)
    {
        int year = LocalDate.now().getYear();
        LocalDate dayBeforeChristmas = LocalDate.of(year, 12, 24);
        LocalDate dayBeforenewYear = LocalDate.of(year, 12, 31);
        return (date.isEqual(dayBeforeChristmas) || date.isEqual(dayBeforenewYear));
    }
}

相关问题