Mockito - NullpointerException when stubbing Method

2022-08-31 07:47:04

所以我开始为我们的Java-Spring项目编写测试。

我使用的是JUnit和Mockito。据说,当我使用当()...然后返回()选项我可以模拟服务,而无需模拟它们左右。所以我想做的是,设置:

when(classIwantToTest.object.get().methodWhichReturnsAList(input))thenReturn(ListcreatedInsideTheTestClass)  

但是无论我做哪个 when-clause,我总是会得到一个 NullpointerException,这当然是有道理的,因为输入是 null。

另外,当我尝试从对象中模拟另一个方法时:

when(object.method()).thenReturn(true)

在那里,我还得到了一个 Nullpointer,因为该方法需要一个未设置的变量。

但我想使用 when()..thenReturn() 来创建这个变量,依此类推。我只是想确保,如果任何类调用此方法,那么无论如何,只需返回true或上面的列表。

这基本上是我这边的误解,还是有其他问题?

法典:

public class classIWantToTest implements classIWantToTestFacade{
        @Autowired
        private SomeService myService;

        @Override
        public Optional<OutputData> getInformations(final InputData inputData) {
            final Optional<OutputData> data = myService.getListWithData(inputData);
            if (data.isPresent()) {
                final List<ItemData> allData = data.get().getItemDatas();
                    //do something with the data and allData
                return data;
            }

            return Optional.absent();
        }   
}

这是我的测试类:

public class Test {

    private InputData inputdata;

    private ClassUnderTest classUnderTest;

    final List<ItemData> allData = new ArrayList<ItemData>();

    @Mock
    private DeliveryItemData item1;

    @Mock
    private DeliveryItemData item2;



    @Mock
    private SomeService myService;


    @Before
    public void setUp() throws Exception {
        classUnderTest = new ClassUnderTest();
        myService = mock(myService.class); 
        classUnderTest.setService(myService);
        item1 = mock(DeliveryItemData.class);
        item2 = mock(DeliveryItemData.class);

    }


    @Test
    public void test_sort() {
        createData();
        when(myService.getListWithData(inputdata).get().getItemDatas());

        when(item1.hasSomething()).thenReturn(true);
        when(item2.hasSomething()).thenReturn(false);

    }

    public void createData() {
        item1.setSomeValue("val");
        item2.setSomeOtherValue("test");

        item2.setSomeValue("val");
        item2.setSomeOtherValue("value");

        allData.add(item1);
        allData.add(item2);


}

答案 1

我遇到了这个问题,我的问题是我用而不是.调用我的方法。所以我有:any()anyInt()

doAnswer(...).with(myMockObject).thisFuncTakesAnInt(any())

我不得不把它改成:

doAnswer(...).with(myMockObject).thisFuncTakesAnInt(anyInt())

我不知道为什么会产生NullPointerException。也许这将有助于下一个可怜的灵魂。


答案 2

尚未存根的方法的默认返回值适用于布尔方法、空集合或返回集合或映射的方法等。falsenull

这也适用于 中的方法调用。在你的例子中,将导致一个NullPointerException,因为它是 - 它以前没有被存根。when(...)when(myService.getListWithData(inputData).get())myService.getListWithData(inputData)null

一种选择是为所有中间返回值创建模拟,并在使用前将其存根。例如:

ListWithData listWithData = mock(ListWithData.class);
when(listWithData.get()).thenReturn(item1);
when(myService.getListWithData()).thenReturn(listWithData);

或者,您可以在创建模拟时指定不同的默认答案,以使方法返回新的模拟而不是 null:RETURNS_DEEP_STUBS

SomeService myService = mock(SomeService.class, Mockito.RETURNS_DEEP_STUBS);
when(myService.getListWithData().get()).thenReturn(item1);

您应该阅读Mockito.RETURNS_DEEP_STUBS Javadoc,其中更详细地解释了这一点,并且还有一些关于其用法的警告。

我希望这有帮助。请注意,您的示例代码似乎存在更多问题,例如缺少断言或验证语句以及在模拟上调用 setter(这没有任何影响)。