Android: 如何对 Observable concatMap 与 mockK 进行单元测试

Android: How to unit test Observable concatMap compose with mockK

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

我正在使用 RxJava 和 mockk 库。

我一直在尝试使用两个 separetes every 语句来模拟结果。 但是当我先打电话时

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

然后

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

interactor.isServerConfigurationEmpty()returnsObservableJust。好的

但是interactor.isServerConfigurationEmpty().compose()returnsNPE,作曲家为空

当我先写的时候

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

然后

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

interactor.isServerConfigurationEmpty().compose()returnsObservableJust。好的。

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

这是我的测试class

@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)
                })
        }
    }

我通过模拟 schedulerProvider.ioToMainObservableScheduler() 的结果解决了这个问题。

主要问题是使用 Schedulers.io()AndroidSchedulers.mainThread()。然后我在 medium 上发现了这个惊人的 post。 Fixing unit test issue of RxJava Chain and Kotlin.

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

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

所以,现在 mi 测试看起来像:

@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()
}

希望这对某人有所帮助。