Reputation: 816
In the following code, I want to test whether "DisplayHelper.displayAlert" has been called. I am dependency-injecting DisplayHelper
and AuthService
mock objects, and using PromiseKit
In My ViewController:
@IBAction func submitButtonPressed(sender: AnyObject) {
AuthService.updateUser(["zipcode": self.zipcodeTextField.text!])
.then { user -> Void in
// sucess code
}.error { error -> Void in
self.DisplayHelper.displayAlert("Zipcode Not Found", message: "We can't find that zipcode... please try again.", callingViewController: self)
}
}
Here are the not-working tests:
func testSubmitButtonServerCantFindZipcode() {
vc.zipcodeTextField.text = "00000"
vc.submitButtonPressed(self)
// called AuthService (passes)
XCTAssertEqual(authServiceMock.updateUserCalled, true)
// called displayAlert (fails because tests run before DisplayAlert is called)
XCTAssertEqual(displayHelperMock.displayAlertCalled, true)
}
How do I get the tests to wait for all of the code to execute before the assertions?
Upvotes: 2
Views: 554
Reputation: 17471
When testing asynchronous code with XCTest you need to use XCTestExpectation
.
You can rewrite the test code like this:
let e = expectationWithDescription("display alert")
waitForExpectationsWithTimeout(3) { error in
XCTAssertEqual(displayHelperMock.displayAlertCalled, true)
}
Now the only missing piece to make the test work is finding a place where to call expectation.fulfill()
. The most appropriate place would be in your AuthService
mock, after the success and failure callbacks are run.
If I can suggest you something though, writing tests that asser whether certain methods have been called is not a safe approach to testing, as you are just testing implementation rather than behaviour.
What could be a better approach is to test the two componets independently. TestAuthService
making sure that both the success and failure path execute as expected, and the DisplayHelper
to make sure that the alert view is actually added to the view hierarchy.
This article could be a useful place to start to find out how unit test alerts, and this post is a good read on why and how to avoid mocks.
Upvotes: 2