Mockito-存根方法时为NullpointerException

问题描述 投票:48回答:13

因此,我开始为我们的Java Spring项目编写测试。

我使用的是JUnit和Mockito。有人说,当我使用when()... thenReturn()选项时,可以模拟服务,而无需模拟它们。所以我想做的是设置:

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

但是不管我在什么时候做,总是会得到一个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);


}
java testing junit mockito stubbing
13个回答
48
投票

尚未被存根的方法的默认返回值对于布尔方法为false,对于返回集合或映射的方法为空集合或映射,否则为null。>

这也适用于when(...)中的方法调用。在您的示例中,when(myService.getListWithData(inputData).get())将导致NullPointerException,因为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(这没有任何作用)。


0
投票

Ed Webb的answer为我提供了帮助。而且,您也可以尝试添加


0
投票

就我而言,我错过了第一个添加


0
投票

这些答案都不适合我。此答案不能解决OP的问题,但由于此帖子是出现在Google搜索此问题的唯一帖子,因此我在此处分享我的答案。


0
投票

以上答案都没有帮助我。我在努力理解为什么代码在Java中有效,而在Kotlin中not


95
投票

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


42
投票

我有同样的问题,我的问题仅仅是我没有使用@RunWith正确地注释该类。在您的示例中,请确保您具有:


7
投票

对我来说,获得NPE的原因是,我在模拟基元时使用了Mockito.any()。我发现通过切换到模仿者使用正确的变体可以消除错误。


4
投票

对于将来的读者,使用模拟时导致NPE的另一个原因是忘记像这样初始化模拟:


3
投票

角落情况:


1
投票
@RunWith(MockitoJUnitRunner.class) //(OR) PowerMockRunner.class

@PrepareForTest({UpdateUtil.class,Log.class,SharedPreferences.class,SharedPreferences.Editor.class})
public class InstallationTest extends TestCase{

@Mock
Context mockContext;
@Mock
SharedPreferences mSharedPreferences;
@Mock
SharedPreferences.Editor mSharedPreferenceEdtor;

@Before
public void setUp() throws Exception
{
//        mockContext = Mockito.mock(Context.class);
//        mSharedPreferences = Mockito.mock(SharedPreferences.class);
//        mSharedPreferenceEdtor = Mockito.mock(SharedPreferences.Editor.class);
    when(mockContext.getSharedPreferences(Mockito.anyString(),Mockito.anyInt())).thenReturn(mSharedPreferences);
    when(mSharedPreferences.edit()).thenReturn(mSharedPreferenceEdtor);
    when(mSharedPreferenceEdtor.remove(Mockito.anyString())).thenReturn(mSharedPreferenceEdtor);
    when(mSharedPreferenceEdtor.putString(Mockito.anyString(),Mockito.anyString())).thenReturn(mSharedPreferenceEdtor);
}

@Test
public void deletePreferencesTest() throws Exception {

 }
}

1
投票

您需要初始化MockitoAnnotations.initMocks(this)方法来初始化带注释的字段。


0
投票

面对同样的问题,对我有用的解决方案:

© www.soinside.com 2019 - 2024. All rights reserved.