2017-02-17 34 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()); 
} 
相關問題