Search code examples
swiftunit-testingasynchronousasync-awaitxctest

XCTAssertThrowsError for async/await function


Given the following method signature, how can I test this method:

func doTheJob(param: String) async throws -> String

with XCTAssertThrowsError?

I've tried XCTAssertThrowsError(await object.doTheJob(param: "")) but getting an error:

'async' call in an autoclosure that does not support concurrency

What would be a solution to this problem?


Solution

  • It would be a good idea to submit a feature request for this using Feedback Assistant but for now you can create a func that XCTFail if the expression does not throw

    func xCTAssertThrowsError<T>(_ expression: @autoclosure () async throws -> T) async {
        do {
            _ = try await expression()
            XCTFail("No error was thrown.")
        } catch {
            //Pass
        }
    }
    

    Then you can use it something like.

    func testExample() async throws {
    
        await xCTAssertThrowsError(try await doSomething())
    }
    

    If you want to use the errorHandler and other arguments you can implement those too in your custom func.

    func xCTAssertThrowsError<T>(
        _ expression: @autoclosure () async throws -> T,
        _ message: @autoclosure () -> String = "",
        file: StaticString = #filePath,
        line: UInt = #line,
        _ errorHandler: (Error) -> Void = { _ in }
    ) async {
        do {
            _ = try await expression()
            XCTFail(message())
        } catch {
            errorHandler(error)
        }
    }