3

I want to test asynchronous functions in Swift, hence as shown below, I created a XCTestExpectation and passed it on to an XCTWaiter. Now, irrespective if the expectation is fulfilled or not, I get a test ran successfully always.

Can you point out what is wrong in the code. I followed exactly a blog which was made for Swift 3, however, I am running Swift 4. Is that the issue?

func testAsyncFunction() {
        let expectation = XCTestExpectation(description: "Some description")
        vc.asyncFunction(5) { (abc: Int) -> Int in
            if (abc != 25) {
                // expectation.fulfill()
            }
            return 0
        }
        _ = XCTWaiter.wait(for: [expectation], timeout: 2.0)
    }
rahulg
  • 2,183
  • 3
  • 33
  • 47
  • 1
    It's easier to use XCTestCase's convenience functions: `let asyncCompleted = self.expectation(description: "Some description")` and `self.waitForExpectations(timeout: 2.0)`. Seems like XCTWaiter.wait doesn't just returns result and not fails the test in case of timeout. – Maxim Kosov Apr 24 '18 at 11:48
  • worked as expected, thanks – rahulg Apr 24 '18 at 13:22

1 Answers1

12

XCTWaiter.wait returns an XCTWaiter.Result which you should be observing.

func testAsyncFunction() {
    let expectation = XCTestExpectation(description: "Some description")
    vc.asyncFunction(5) { (abc: Int) -> Int in
        if (abc != 25) {
            // expectation.fulfill()
        }
        return 0
    }

    let result = XCTWaiter.wait(for: [expectation], timeout: 2.0) // wait and store the result
    XCTAssertEqual(result, .timedOut) // check the result is what you expected
}
Oletha
  • 7,324
  • 1
  • 26
  • 46
  • 2
    to add onto this answer. if the expectation is fulfilled or that's what you expect it to be then your assert should be change to: `XCTAssertEqual(result, .completed)` – mfaani Nov 21 '19 at 05:06