How do you write a unit test that checks whether an async function doesn't timeout?
I'm trying with regular XCTestExpectation
, but because await
suspends everything, it can't wait for the expectation.
In the code below, I'm checking that loader.perform()
doesn't take more than 1 second to execute.
func testLoaderSuccess() async throws {
let expectation = XCTestExpectation(description: "doesn't timeout")
let result = try await loader.perform()
XCTAssert(result.value == 42)
wait(for: [expectation], timeout: 1) // execution never gets here
expectation.fulfill()
}
CodePudding user response:
You need to structure this in a different way.
You need to create a new Task
. In this Task
execute and await the async code. After awaiting fulfill the expectation.
Your code did not work because the Thread the Test runs on will stop at wait(for:
for the expectation to fulfill, what it never does as the line comes after wait(for:
.
func testLoaderSuccess() throws {
let expectation = XCTestExpectation(description: "doesn't timeout")
Task{
try await Task.sleep(nanoseconds: 500_000_000)
expectation.fulfill()
}
wait(for: [expectation], timeout: 1)
// Assertions here because only then is assured that
// everything completed
}
CodePudding user response:
The sequence that worked for me both locally and on CI is the following:
func testLoaderSuccess() async throws {
Task {
let result = try await loader.perform()
XCTAssert(result.value == 42)
expectation.fulfill()
}
wait(for: [expectation], timeout: 1)
}