首页 > 解决方案 > Android:如何使用 mockK 对 Observable concatMap 组合进行单元测试

问题描述

我需要使用 concatMap 对 Observable 进行单元测试,然后进行组合。

我正在使用 RxJava 和 mockk 库。

我一直在尝试使用两个单独every的语句来模拟结果。但是当我第一次打电话时

every {
    remoteLocalInteractor.isServerConfigurationEmpty()
        .compose(schedulerProvider.ioToMainObservableScheduler())
} returns  Observable.just(true)

进而

every {
    remoteLocalInteractor.isServerConfigurationEmpty()
} returns  Observable.just(true)

interactor.isServerConfigurationEmpty()返回ObservableJust。好的

interactor.isServerConfigurationEmpty().compose()返回NPE,作曲家为空

情况1

当我先写

every {
    interactor.isServerConfigurationEmpty().compose(...)
} returns Observable.just(true)

进而

every { 
    interactor.isServerConfigurationEmpty() 
} returns Observable.just(true)

interactor.isServerConfigurationEmpty().compose()返回ObservableJust。好的。

但是interactor.isServerConfigurationEmpty()返回Observable(child of #1#3),我需要有一个ObservableJust对象

案例2

这是我的测试课

@RunWith(JUnit4::class)
class RemoteLocalPresenterTest : BaseTest() {

  @Before
  override fun setup() {
      super.setup()
      remoteLocalInteractor = spyk()
      remoteLocalPresenter = RemoteLocalPresenter(
          remoteLocalInteractor,
          schedulerProvider,
          compositeDisposable,
          remoteLocalConfigConverter
      )
      remoteLocalPresenter.onAttach(remoteLocalView)
  }

  @Test
  fun 
  testShouldSaveDefaultConfigurations_serverConfigurationsIsEmpty_onSuccess(){
      every {
          remoteLocalInteractor.isServerConfigurationEmpty()
      } returns  Observable.just(true)

      every {
          remoteLocalInteractor.isServerConfigurationEmpty()
              .compose(schedulerProvider.ioToMainObservableScheduler())
      } returns  Observable.just(true)

      remoteLocalPresenter.shouldSaveDefaultConfigurations(activity)
  }
}

这是我要测试的功能

override fun shouldSaveDefaultConfigurations(activity: BaseActivity) {
        getView()?.showProgress()
        interactor?.let { interactor ->
            interactor.isServerConfigurationEmpty().concatMap { isEmpty ->
                if (isEmpty)
                    Observable.just(ClientTO())
                else
                    Observable.just(false)
            }.compose(schedulerProvider.ioToMainObservableScheduler())
                .subscribe({ res ->
                    when (res) {
                        is ClientTO -> {
                            getView()?.hideProgress()
                            ...
                            ...
                            ...
                        }
                        else -> {
                            getView()?.let {
                                ...
                                ...
                                ...
                            }
                        }
                    }
                }, { err ->
                    CommonUtil.handleErrors(err)
                })
        }
    }

标签: androidunit-testingkotlinrx-java2mockk

解决方案


我通过模拟我的schedulerProvider.ioToMainObservableScheduler().

主要问题是使用Schedulers.io()and AndroidSchedulers.mainThread()。然后我在媒体上发现了这个惊人的帖子。修复 RxJava Chain 和 Kotlin 的单元测试问题

所以在我需要进行可观察的调用之前,我会这样做。

every {
    schedulerProvider.ioToMainObservableScheduler<Scheduler>()
} answers {
    ObservableTransformer { upstream -> 
        upstream.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) 
    }
}

所以,现在 mi test 看起来像:

@Test
fun testShouldSaveDefaultConfigurations_serverConfigurationsIsEmpty_onSuccess() {
    every {
        schedulerProvider.ioToMainObservableScheduler<Scheduler>()
    } answers {
        ObservableTransformer { upstream -> 
           upstream
               .subscribeOn(Schedulers.io())
               .observeOn(AndroidSchedulers.mainThread()) 
        }
    }

    every {
        remoteLocalInteractor.isServerConfigurationEmpty()
    } returns Observable.just(true)

    remoteLocalPresenter.shouldSaveDefaultConfigurations(activity)

    verify(remoteLocalPresenter.getView())?.hideProgress()
}

希望这可以帮助某人。


推荐阅读