2017-02-17 8 views
0

Это однозначно дубликат другого вопроса на How to make mock to void methods with mockito. Есть и ряд похожих вопросов/ответов, но никто мне не помог. Поскольку сотни разработчиков приняли некоторые ответы, я, вероятно, ошибаюсь где-то и понятия не имею, где моя проблема!Как издеваться над методом void с помощью 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()); 
} 
Смежные вопросы