dloomb
dloomb

Reputation: 1972

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.

Upvotes: 3

Views: 2590

Answers (1)

mokagio
mokagio

Reputation: 17461

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.

Upvotes: 8

Related Questions