Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 766
user2924482 Avatar asked Apr 26 '17 23:04

user2924482


1 Answers

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)
like image 78
Paulo Mattos Avatar answered Oct 22 '22 01:10

Paulo Mattos