2017-02-17 90 views
0

这是在How to make mock to void methods with mockito的另一个相同的问题的复制副本。还有一堆类似的问题/答案,但没有人帮助我。由于有数百名开发人员接受了一些答案,我可能在某处出错,不知道我的问题在哪里!如何使用PowerMockito模拟无效方法?

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

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)

因此,任何帮助,将不胜感激。谢谢。

回答

0

你在给定的代码逻辑是这样做,当你路过mActivity对象什么:PowerMockito.doNothing().when(spy).cleanAllMessages(mActivity);

但是你实际上传递为空: 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 
+0

感谢您的评论。是的,我实际上在那个链接中看到了类似的答案,并且在基于这种方法进行测试之后没有得到我预期的结果。我不知道为什么,但没有工作,我得到了类似的结果,我在我的问题中提到。 – Hesam

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()); 
} 
相关问题