MVICore icon indicating copy to clipboard operation
MVICore copied to clipboard

Features testing.

Open linyaDev opened this issue 5 years ago • 3 comments

Hi guys. Do you have any examples, best practices how you tests yours features?

linyaDev avatar Sep 09 '19 13:09 linyaDev

You can unit test the individual pieces if needed (Reducer, Actor). You can also unit test the whole Feature by setting it up with some specific initial state, feeding it a Wish, and checking if new state is as expected / expected News are triggered.

zsoltk avatar Sep 12 '19 11:09 zsoltk

I'm trying to test my feature which initially uses a Bootstrapper and PostProcessor to fetch data from a remote database. This should emit the result directly after the initial state. In my test I use a fake implementation which returns fake data immediately. However, even if I use TestObserver#await and Test Scheduler, the test always fails because the reducer invocation doesn't happen before the test is terminated.

Are there any best practices to fix this issue?

`@Test fun fetches_messsages() = runBlocking<Unit>{ val t = TestObserver<HomeFeatureState>() homeFeature.subscribe(t)

    t.await(3L, TimeUnit.SECONDS)
    t.assertValueCount(2)
}

`

The rule i ues: `class TrampolineSchedulerRule : TestRule {

val testScheduler = TestScheduler()

override fun apply(base: Statement, d: Description): Statement {
    return object : Statement() {

        override fun evaluate() {
            RxJavaPlugins.setIoSchedulerHandler { Schedulers.trampoline() }
            RxJavaPlugins.setComputationSchedulerHandler { Schedulers.trampoline() }
            RxJavaPlugins.setNewThreadSchedulerHandler { Schedulers.trampoline() }
            RxAndroidPlugins.setInitMainThreadSchedulerHandler { testScheduler }

            try {
                base.evaluate()
            } finally {
                RxJavaPlugins.reset()
                RxAndroidPlugins.reset()
            }
        }
    }
}

}`

THEAccess avatar Sep 26 '19 20:09 THEAccess

@THEAccess If you would test the actual value, and not just the value count, you would probably find that the single value you get is not the Feature's initial state, but the next one: the state which is the result of completing your Bootstrapper action.

This is because initial state is fired upon Feature creation immediately, and Bootstrapper is also invoked immediately. By the time you subscribe to your Feature, its latest state is the one that is reflected on the receiving end (as if it was a BehaviorSubject).

And, because there are no further actions to execute, no matter how long of a delay you put into place, you're not gonna get another one.

I suggest you read:

  • https://badoo.github.io/MVICore/features/coreconcepts/#features-are-hot-observables
  • https://badoo.github.io/MVICore/bestpractices/delayingbootstrapping/

zsoltk avatar Sep 27 '19 09:09 zsoltk