0

I need to unit test an Observable with concatMap and then compose.

I'am using RxJava and mockk library.

I've been trying to use two separetes every statements to mock the results. But when i call first

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

and then

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

interactor.isServerConfigurationEmpty() returns ObservableJust. All right

But interactor.isServerConfigurationEmpty().compose() returns NPE, composer is null

Case 1

And when i write first

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

and then

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

interactor.isServerConfigurationEmpty().compose() returns ObservableJust. All right.

But interactor.isServerConfigurationEmpty() returns Observable(child of #1#3) and i need to have an ObservableJust Object

Case 2

This is my test 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)
  }
}

And this is my func to be tested

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

1 Answers1

0

I solved by mocking the result of my schedulerProvider.ioToMainObservableScheduler().

The main problem was to work with Schedulers.io() and AndroidSchedulers.mainThread(). Then i found this amazing post on medium. Fixing unit test issue of RxJava Chain and Kotlin.

So before i need to make an observable call i do this.

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

So, now mi test looks like:

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

Hope this helps someone.