这是this question的副本。也有很多类似的问题/答案,但是没有一个帮助我。由于有成百上千的开发人员接受了一些答案,我可能在某个地方错了,也不知道我的问题在哪里!

这是我的示例类,我想测试其方法。

final class NavigationBuilder {

    @VisibleForTesting List<Intent> mIntentList = new ArrayList<>(5);

    @VisibleForTesting
    void addNextScreenBasedOnBookingStatus(final Booking booking) {
        final ChatMsgDbAsyncHelper helper = new ChatMsgDbAsyncHelper();

        if (booking == null) {
            helper.cleanAllMessages(mContext); // <= Crash here
        }

    }
}


这是我的测试课:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ChatMsgDbAsyncHelper.class, SplashActivity.class})
public class NavigationBuilderTest {

    private SplashActivity mActivity;
    private NavigationBuilder mNavBuilder;

    @Before
    public void setUp() throws Exception {

        mActivity = new SplashActivity();
        ISplashView view = mock(ISplashView.class);
        PassengerStorage passengerStorage = mock(PassengerStorage.class);

        mNavBuilder = new NavigationBuilder(mActivity, view, passengerStorage);
    }

    @Test
    public void addNextScreenBasedOnBookingStatus_whenBookingIsNull() throws Exception {
        ChatMsgDbAsyncHelper spy = PowerMockito.spy(new ChatMsgDbAsyncHelper());
        PowerMockito.doNothing().when(spy).cleanAllMessages(mActivity);

        mNavBuilder.addNextScreenBasedOnBookingStatus(null);

        assertTrue(mNavBuilder.mIntentList.isEmpty());
    }
}


测试失败,原因是NullPointerException,因为测试正在helper.cleanAllMessages(mContext);内部运行逻辑。我从上面的模拟中期望的是不应执行这些逻辑。


  由以下原因引起:java.lang.NullPointerException
  com.xxx.xxx.db.entities.ChatMessageTable。(ChatMessageTable.java:23)

最佳答案

给定代码中的逻辑是在传递mActivity对象时不执行任何操作:PowerMockito.doNothing().when(spy).cleanAllMessages(mActivity);

但是您实际传递的是null:
mNavBuilder.addNextScreenBasedOnBookingStatus(null);

另外,您必须在测试类中传递此“间谍”对象,以使模拟逻辑起作用。也许您可以尝试这样的事情-

PowerMockito.whenNew(ChatMsgDbAsyncHelper.class).withNoArguments().thenReturn(spy);
PowerMockito.doNothing().when(spy).cleanAllMessages(mActivity); // or null, as per your requirement


然后将您的mActivity对象传递给该方法:

mNavBuilder.addNextScreenBasedOnBookingStatus(mActivity); // or pass null, as per your requirement

10-04 12:31