方法在单元测试中多次调用,但在代码中不调用



我正在为使用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)

您的真实代码正在onNext中调用onMenuLoaded(items),然后您的模拟可观察量另外从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())
}

问题在于不小心将PowerMockito间谍和Mockito模拟结合在一起。在导入Mockito的间谍时,问题得到了解决。

编辑:我再次遇到同样的问题,解决方案是不同的。看起来同样的原因正在结合PowerMockito和Mockito。这次我通过添加一个doNothing块解决了它

    doNothing().`when`(viewModel).myCall(true)

相关内容

  • 没有找到相关文章