user2924482
user2924482

Reputation: 9140

Swift: XCTest delegate/protocol call backs (Unit test)

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.

Upvotes: 13

Views: 8317

Answers (1)

Paulo Mattos
Paulo Mattos

Reputation: 19349

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)

Upvotes: 32

Related Questions