Naknut
Naknut

Reputation: 127

XCTestExpectation does not seem to work in Task()

Im trying to run a test actor that makes a network request and if you call it while it still has a request going it will cancel the first request and throw an CancellationError. Im using a Task() to simulate it being called twice asynchrony and the code seems to be working fine. I can see the correct error being thrown and the catch-block being executed. Below is the code.

func testCancellation() async throws {
    //setup code

    let expectation = XCTestExpectation(description: "Cancellation Error thrown")
    let autocompleteHandler = AutocompleteHandler(session: session)
        
    Task() {
        do {
            let _ = try await autocompleteHandler.autocomplete(query: "Grizzly Bear")
        } catch {
            if error is CancellationError { expectation.fulfill() }
        }
    }
    Task() {
        do {
            let _ = try await autocompleteHandler.autocomplete(query: "Grizzly Bear")
        } catch {
            if error is CancellationError { expectation.fulfill() }
        }
    }
        
    wait(for: [expectation], timeout: 1)
}

When running this I get the following error:

Asynchronous wait failed: Exceeded timeout of 1 seconds, with unfulfilled expectations: "Cancellation Error thrown".

But as I said. I can see the catch-block being executed and the error is of the correct type and expectation.fulfill() is being called.

Upvotes: 2

Views: 1100

Answers (1)

Naknut
Naknut

Reputation: 127

After reading the comment from @Alexander I realized that I do indeed not need to wait for anything. I reformatted the code to the following and now it works.

func testCancellation() async {
    //Setup code

    let autocompleteHandler = AutocompleteHandler(session: session)
        
    async let first = autocompleteHandler.autocomplete(query: "Grizzly Bear")
    async let second = autocompleteHandler.autocomplete(query: "Grizzly Bear")
        
    do {
        let _ = [try await first, try await second]
        XCTFail("Should have thrown cancellation error")
    } catch {
        XCTAssert(error is CancellationError)
    }
}

This works as expected.

Upvotes: 2

Related Questions