3

I am trying to get a better understanding of how to do unit tests with Rx-Kotlin, but I have not been able to successfully set the subject to "completed". As a result, I am always waiting for the timeout of 5 seconds (the onComplete should be immediate) and then fail on assertComplete.

My understanding of awaitTerminalEvent is that it should only block until the onComplete is called. I have also looked into TestScheduler, but I do not believe that it should be required here.

Any help or documentation that can lead me in the right direction would be much appreciated.

@Test
fun testObservable() {
    val subject = BehaviorSubject.create<Int>()
    subject.onNext(0)

    TestSubscriber<Int>().apply {
        subject.subscribe({
            System.out.println(it)
            subject.onNext(1)
            subject.onComplete()
        })

        this.awaitTerminalEvent(5, TimeUnit.SECONDS)
        this.assertComplete()
        this.assertValue(1)
    }
}
yosriz
  • 10,147
  • 2
  • 24
  • 38
sschmitz
  • 432
  • 5
  • 16

1 Answers1

5

You're using the wrong tool in the wrong way...

  • TestSubscriber is for testing Flowable, you should use here TestObserver.
  • you should subscribe with the TestObserver (or TestSubscriber in Flowable), in order for it to monitor emissions and be able to wait for terminal event and assert values. In your code the TestSubscriber is not attached to any stream, so it will never get any event.

trying to mimic your code, it could be something like this:

 @Test
fun testObservable() {
    val subject = BehaviorSubject.create<Int>()
    subject.onNext(0)

    TestObserver<Int>().apply {
        subject.doOnNext {
            System.out.println(it)
            subject.onNext(1)
            subject.onComplete()
        }
                .subscribe(this)

        this.awaitTerminalEvent(5, TimeUnit.SECONDS)
        this.assertComplete()
        this.assertValue(1)
    }
}  

as you can see, I'm using TestObserver the subscribe is done with the TestObserver object, and the subject onNext(), onComplete() moved to the doOnNext(). the test will fail as you have two emitted values, while the test assert only for single '1' value.

Generally speaking, it's kind of wrong, that you using subject to emit again in the onNext() and then call onComplete(), you can subscribe before and then emit outside. something like this:

TestObserver<Int>().apply {
        subject.subscribe(this)
        subject.onNext(1)
        subject.onComplete()
        ....
}
yosriz
  • 10,147
  • 2
  • 24
  • 38
  • I know I shouldn't be emitting inside of the subject like that, I was just trying to write an odd test. Thank you so much! – sschmitz May 04 '17 at 11:30