Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RxSwift Unit Testing

I have a simple RxSwift Observable sequence that I am trying to unit test.

    var pass = false
    _ = service!.authenticate().subscribeNext { res in
        XCTAssert(res.tokenValue == "abc123")
        pass = true
    }
    XCTAssertTrue(pass)

This test will fail intermittently as if the subscribeNext block is not always hit. Any ideas on what I'm doing wrong?

Edit 1

This authenticate call is simply returning static JSON data and is not actually hitting the network.

like image 304
dloomb Avatar asked Nov 17 '25 12:11

dloomb


1 Answers

Your problem is most likely due to either one of these two issues:

  1. The test hits the network
  2. The test is written in a synchronous way, but the behaviour tested is asynchronous.

Regarding hitting the network in your tests: This is generally a bad idea, unless you are doing integration testing. The network is unreliable, it can timeout or fail. You can find more info on why hitting the network in your test is not a good idea here.

Regarding asynchronous testing: What is happening is that your assertion is executed by the test before the next event is sent by the observable.

You could rewrite your test like this:

let service = SomeService()

let expectation = expectationWithDescription("subscribeNext called")

_ = service!.authenticate().subscribeNext { res in
    XCTAssert(res.tokenValue == "abc123")
    expectation.fulfill()
}

waitForExpectationsWithTimeout(1) { error in
  if let error = error {
    XCTFail("waitForExpectationsWithTimeout errored: \(error)")
  }
}

You can find more info on asynchronous tests here.

like image 57
mokagio Avatar answered Nov 19 '25 01:11

mokagio



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!