如何使用PowerMockito模拟void方法?

时间:2017-02-17 07:32:34

标签: java android unit-testing powermockito spy

这是this question的副本。还有许多类似的问题/答案,但没有人帮助我。由于有数百名开发人员接受了一些答案,我可能在某处错了,不知道我的问题在哪里!

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

snippet, status

这是我的测试类:

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内运行逻辑。我对上述模拟的期望是不应该执行这些逻辑。

  

引起:java.lang.NullPointerException at   com.xxx.xxx.db.entities.ChatMessageTable。(ChatMessageTable.java:23)

2 个答案:

答案 0 :(得分:0)

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

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

此外,你必须通过这个&#34;间谍&#34;测试类中的对象使您的模拟逻辑工作。也许你可以尝试这样的事情 -

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

答案 1 :(得分:0)

问题是我的理解:)

我用以下方法更改了测试方法的签名,并可以测试它。所以在这种情况下,我将ChatMsgDbAsyncHelper的实例传递给方法,而不是在方法中创建它。

@VisibleForTesting
    void addNextScreenBasedOnBookingStatus(final Booking booking, final ChatMsgDbAsyncHelper chatMsgHelper) {
...
}

现在测试工作正常:

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

    mNavBuilder.addNextScreenBasedOnBookingStatus(null, mChatMsgHelper);

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