← All daysDay 37 of 49 · Part 9: Swift concurrency
Day 37

Testing async code

These are the lesson notes for this day. Its build-along tutorial and flash cards have not been written yet.

Lesson 42

Testing async code

A test function can be async, so testing asynchronous code is mostly straightforward: await the call, then check the result. In Swift Testing you write @Test func loads() async throws { … } and check with #expect. XCTest supports async test methods in the same way. For code that still uses callbacks, Swift Testing provides confirmation { }, and XCTest provides XCTestExpectation with await fulfillment(of:).

What makes asynchronous code testable is what makes any code testable: its dependencies are passed in. A model that calls URLSession.shared directly cannot be tested without a network. A model that is handed a fetch function can be given a stub. Swift 6.4 adds test cancellation and warning-level issues, and lets Swift Testing and XCTest be mixed in one target while you migrate.

Example
struct WeatherModel {
    let fetch: () async throws -> Int            // the dependency is passed in

    func summary() async -> String {
        do {
            return "It is \(try await fetch()) degrees"
        } catch {
            return "Unavailable"
        }
    }
}

@Test func showsTheTemperature() async {
    let model = WeatherModel(fetch: { 72 })      // a stub, not the network
    #expect(await model.summary() == "It is 72 degrees")
}

@Test func showsAFallbackWhenTheFetchFails() async {
    let model = WeatherModel(fetch: { throw URLError(.notConnectedToInternet) })
    #expect(await model.summary() == "Unavailable")
}
Exercise

Write tests for a model that loads data: one for success and one for failure, using a stubbed fetch function. Then test a callback-based API using confirmation.

After this lesson you should be able to answer
  1. How do you write a test for an async function?
  2. When do you need confirmation or an expectation?
  3. What must be true of a model before you can test its networking logic offline?
Resources