I need to create some unit test for delegate/protocol call backs. Here is an example of the implementation I'm trying to test:
protocol SomethingWithNumbersDelegate: class {
func somethingWithDelegate(results:Int)
}
class SomethingWithNumbers {
var delegate: SomethingWithNumbersDelegate? = nil
func doAsyncStuffWithNumbers(number:Int) {
var numbers = Int()
/*
doing some with the input
*/
self.delegate?.somethingWithDelegate(results: numbers)
}
}
I haven't found a create the unit test (XCTest) to test the delegate response.
I'll really appreciate your help.
You can use the XCTestExpectation
facility for this. For instance:
class NumbersTest: XCTestCase, SomethingWithNumbersDelegate {
func testAsynchronousNumbers() {
numbersExpectation = expectation(description: "Numbers")
let numbers = SomethingWithNumbers()
numbers.delegate = self
numbers.doAsyncStuffWithNumbers(number: 123)
// Waits 100 seconds for results.
// Timeout is always treated as a test failure.
waitForExpectations(timeout: 100)
XCTAssertEqual(self.results, 456)
}
private var numbersExpectation: XCTestExpectation!
private var results: Int!
func somethingWithDelegate(results: Int) {
self.results = results
numbersExpectation.fulfill()
}
}
Asynchronous testing was made a lot easier with the introduction of expectations by Xcode 6. Expectations are created by helper methods on XCTestCase
, such as:
func expectation(description: String) -> XCTestExpectation
Creates and returns an expectation associated with the test case.
Update. For those running Xcode 9, this is now a preferred idiom for waiting on a given XCTestExpectation
instance (i.e., instead of the older waitForExpectations
method):
wait(for: [numbersExpectation], timeout: 100)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With