swift-dependenciesで複数テストを走らせても失敗しないための知見

2025/02/24に公開

概要

swift-dependenciesを使用した際に、テストが失敗したことにより分かった知見の備忘録です。
具体的には、他のテストのモックインスタンスがインジェクトされてしまってテスト複数実行時だけ失敗するようになってしまったDependenciesの回避方法です。

結論

import Dependencies

struct Service: Sendable, DependencyKey {
    @Dependency(Repository.self) var repository

    // 🙅‍♂️ static let liveValue = Self()
    // 🙆‍♂️ static var liveValue: Self { .init() }
    static var liveValue: Self { .init() }
    ...
}

解説

以下のようにServiceを使用するアプリケーションのテストを複数走らせた場合、まず、テストケース1で、Service.liveValueのServiceのインスタンスが作成されて静的プロパティとして固定化されます。次に、テストケース2を実行してもliveValueは固定化されたままなのでテストケース1のリポジトリのモックが使用されてしまいます。

import Dependencies
import Testing

struct Application {
    @Dependency(Service.self) var service

    func run() { ... }
}

@Test func テストケース1() {
    let sut = withDependencies {
        $0[Repository.self] = mock1()
    } operation: {
        Application()
    }

    app.run()

    #expect(...)
}

@Test func テストケース2() {
    let sut = withDependencies {
        $0[Repository.self] = mock2()
    } operation: {
        Application()
    }

    app.run()

    #expect(...)
}

そこで、

static var liveValue: Self { .init() }

に変更することで、毎回依存が解決され複数テストを走らせても失敗しなくなります。

Discussion