Метод вызывается несколько раз в модульных тестах, но не в коде - PullRequest
0 голосов
/ 28 декабря 2018

Я пишу модульные тесты в класс, который использует RxJava 2. Когда onNext () вызывается для наблюдателя, я ожидаю, что onMenuLoaded() будет вызван один раз.В коде он вызывается успешно один раз.Но когда я тестирую этот фрагмент в модульных тестах, метод вызывается 3 раза.

Вопрос в том, как сделать так, чтобы он вызывался только один раз в тестах, и почему он вызывается больше раз в тестах, чем в реальном коде.

//in ViewModel class, under testing
fun loadMenu() {       
        menuInteractorImpl.getMainMenu()?.subscribeOn(Schedulers.io())?.observeOn(AndroidSchedulers.mainThread())?.subscribe(
                { items ->
                    onMenuLoaded(items)
                },
                { error ->
                    //error handling logic
                }
                )?.let { compositeDisposables.add(it) }
}
    //Test
@RunWith(PowerMockRunner::class)
@PowerMockRunnerDelegate(MockitoJUnitRunner::class)
@PrepareForTest(MenuInteractorImpl::class, MainMenuViewModel::class)
class MainMenuViewModelTest {

    @get:Rule
    var instantExecutorRule = InstantTaskExecutorRule()

    companion object {
        @ClassRule
        @JvmField
        val schedulers = RxImmediateSchedulerRule()
    }

    @Before
    fun setUp() {
        doNothing().`when`(viewModel).startTimerToScrollViewPager()
    }

    @Test
    fun `test load menu calls onMenuLoaded when success`() {            
            val mockObservable = Observable.just(mockDataFactory.mockMenu).doOnNext {

            viewModel.onMenuLoaded(it)
        }.subscribeOn(Schedulers.newThread())
        Mockito.`when`(menuInteractorImpl.getMainMenu()).thenReturn(mockObservable)

        viewModel.loadMenu() //this method is called 3 times
        Mockito.verify(viewModel, times(1)).onMenuLoaded(any())
    }

Из журналов показано, гдеметод называется

viewModel.loadMenu();
-> at com.example.mainmenu.MainMenuViewModelTest.test load menu calls onMenuLoaded when success(MainMenuViewModelTest.kt:88)

viewModel.loadMenu();
-> at org.powermock.core.MockGateway.doMethodCall(MockGateway.java:182)

viewModel.loadMenu();
-> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

РЕШЕНИЕ: Проблема была в случайном объединении PowerMockito spy и Mockito mock.При импорте spy в Mockito проблема была решена.

1 Ответ

0 голосов
/ 28 декабря 2018

Ваш реальный код вызывает onMenuLoaded(items) в onNext, и затем ваша фиктивная наблюдаемая дополнительно вызывает его из doOnNext.

Вам необходимо удалить часть doOnNext вашей фиктивной наблюдаемой:

@Test
fun `test load menu calls onMenuLoaded when success`() {            
    val mockObservable = Observable.just(mockDataFactory.mockMenu)
                                .subscribeOn(Schedulers.newThread())
    Mockito.`when`(menuInteractorImpl.getMainMenu()).thenReturn(mockObservable)

    viewModel.loadMenu() //this method is called 3 times
    Mockito.verify(viewModel, times(1)).onMenuLoaded(any())
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...