Source profileQuality 66/100

affaan-m/ECC/docs/ja-JP/skills/swift-protocol-di-testing/SKILL.md

swift-protocol-di-testing

Use it for testing and engineering tasks; the detail page covers purpose, installation, and practical steps.

Source repository stars
234,327
Declared platforms
0
Static risk flags
0
Last source update
2026-07-27
Source checked
2026-07-28

Decision brief

What it does—and where it fits

外部の依存関係(ファイルシステム、ネットワーク、iCloud)を小さく焦点を絞ったプロトコルとして抽象化することで、SwiftコードをテストしやすくするパターンI/Oなしの決定論的テストをサポートする。

Best for

    Not for

    • Tasks that require unconfirmed production actions or broad system permissions.
    • Environments where the pinned source and install steps cannot be inspected.

    Compatibility matrix

    Platform support, with evidence labels

    PlatformStatusEvidenceWhat to check
    CodexNot declaredNo explicit evidencePortability before use
    Claude CodeNot declaredNo explicit evidencePortability before use
    CursorNot declaredNo explicit evidencePortability before use
    Gemini CLINot declaredNo explicit evidencePortability before use
    Open the compatibility checker

    Installation

    Inspect first. Install second.

    The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

    Source-detected install commandSource
    npx skills add https://github.com/affaan-m/ECC --skill "docs/ja-JP/skills/swift-protocol-di-testing"
    Safe inspection promptEditorial

    Inspect the Agent Skill "swift-protocol-di-testing" from https://github.com/affaan-m/ECC/blob/4e973d3eaf92d97f8d2e2d8abb39d8bdc8711b38/docs/ja-JP/skills/swift-protocol-di-testing/SKILL.md at commit 4e973d3eaf92d97f8d2e2d8abb39d8bdc8711b38. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

    Workflow

    What the source asks the agent to do

    1. 01

      起動条件

      ファイルシステム、ネットワーク、または外部APIにアクセスするSwiftコードを書く場合 実際の障害を起こさずにエラー処理パスをテストする必要がある場合 異なる環境(アプリ、テスト、SwiftUIプレビュー)で動作するモジュールを構築する場合 Swift並行処理(Actor、Sendable)をサポートするテスト可能なアーキテクチャを設計する場合

      ファイルシステム、ネットワーク、または外部APIにアクセスするSwiftコードを書く場合実際の障害を起こさずにエラー処理パスをテストする必要がある場合異なる環境(アプリ、テスト、SwiftUIプレビュー)で動作するモジュールを構築する場合
    2. 02

      コアパターン

      本番コードはデフォルト値を使用し、テストはモックを注入する。

      本番コードはデフォルト値を使用し、テストはモックを注入する。
    3. 03

      1. 小さく焦点を絞ったプロトコルを定義する

      Review the “1. 小さく焦点を絞ったプロトコルを定義する” section in the pinned source before continuing.

      Review and apply the “1. 小さく焦点を絞ったプロトコルを定義する” source section.
    4. 04

      2. デフォルト(本番用)実装を作成する

      Review the “2. デフォルト(本番用)実装を作成する” section in the pinned source before continuing.

      Review and apply the “2. デフォルト(本番用)実装を作成する” source section.

    Permission review

    Static risk signals and limitations

    No configured static risk pattern was detected

    This is not proof of safety. Runtime behavior, indirect dependencies, and hidden external systems are outside the static scan.

    Evidence record

    Why each signal appears

    EvidenceSourceComputedTestedEditorial
    SignalValueEvidence typeMeaning
    Quality score66/100ComputedDocumentation, specificity, maintenance, and trust rules
    Repository stars234,327SourceRepository attention, not individual Skill quality
    Compatibility0 platformsSourceDeclared in the catalog source record
    Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

    Pinned source

    Provenance and original SKILL.md

    Repository
    affaan-m/ECC
    Skill path
    docs/ja-JP/skills/swift-protocol-di-testing/SKILL.md
    Commit
    4e973d3eaf92d97f8d2e2d8abb39d8bdc8711b38
    License
    MIT
    Collected
    2026-07-28
    Default branch
    main
    View the original SKILL.md

    プロトコルベースのSwift依存性注入テスト

    外部の依存関係(ファイルシステム、ネットワーク、iCloud)を小さく焦点を絞ったプロトコルとして抽象化することで、SwiftコードをテストしやすくするパターンI/Oなしの決定論的テストをサポートする。

    起動条件

    • ファイルシステム、ネットワーク、または外部APIにアクセスするSwiftコードを書く場合
    • 実際の障害を起こさずにエラー処理パスをテストする必要がある場合
    • 異なる環境(アプリ、テスト、SwiftUIプレビュー)で動作するモジュールを構築する場合
    • Swift並行処理(Actor、Sendable)をサポートするテスト可能なアーキテクチャを設計する場合

    コアパターン

    1. 小さく焦点を絞ったプロトコルを定義する

    各プロトコルは1つの外部関心事のみを処理する。

    // File system access
    public protocol FileSystemProviding: Sendable {
        func containerURL(for purpose: Purpose) -> URL?
    }
    
    // File read/write operations
    public protocol FileAccessorProviding: Sendable {
        func read(from url: URL) throws -> Data
        func write(_ data: Data, to url: URL) throws
        func fileExists(at url: URL) -> Bool
    }
    
    // Bookmark storage (e.g., for sandboxed apps)
    public protocol BookmarkStorageProviding: Sendable {
        func saveBookmark(_ data: Data, for key: String) throws
        func loadBookmark(for key: String) throws -> Data?
    }
    

    2. デフォルト(本番用)実装を作成する

    public struct DefaultFileSystemProvider: FileSystemProviding {
        public init() {}
    
        public func containerURL(for purpose: Purpose) -> URL? {
            FileManager.default.url(forUbiquityContainerIdentifier: nil)
        }
    }
    
    public struct DefaultFileAccessor: FileAccessorProviding {
        public init() {}
    
        public func read(from url: URL) throws -> Data {
            try Data(contentsOf: url)
        }
    
        public func write(_ data: Data, to url: URL) throws {
            try data.write(to: url, options: .atomic)
        }
    
        public func fileExists(at url: URL) -> Bool {
            FileManager.default.fileExists(atPath: url.path)
        }
    }
    

    3. テスト用のモック実装を作成する

    public final class MockFileAccessor: FileAccessorProviding, @unchecked Sendable {
        public var files: [URL: Data] = [:]
        public var readError: Error?
        public var writeError: Error?
    
        public init() {}
    
        public func read(from url: URL) throws -> Data {
            if let error = readError { throw error }
            guard let data = files[url] else {
                throw CocoaError(.fileReadNoSuchFile)
            }
            return data
        }
    
        public func write(_ data: Data, to url: URL) throws {
            if let error = writeError { throw error }
            files[url] = data
        }
    
        public func fileExists(at url: URL) -> Bool {
            files[url] != nil
        }
    }
    

    4. デフォルトパラメーターで依存関係を注入する

    本番コードはデフォルト値を使用し、テストはモックを注入する。

    public actor SyncManager {
        private let fileSystem: FileSystemProviding
        private let fileAccessor: FileAccessorProviding
    
        public init(
            fileSystem: FileSystemProviding = DefaultFileSystemProvider(),
            fileAccessor: FileAccessorProviding = DefaultFileAccessor()
        ) {
            self.fileSystem = fileSystem
            self.fileAccessor = fileAccessor
        }
    
        public func sync() async throws {
            guard let containerURL = fileSystem.containerURL(for: .sync) else {
                throw SyncError.containerNotAvailable
            }
            let data = try fileAccessor.read(
                from: containerURL.appendingPathComponent("data.json")
            )
            // Process data...
        }
    }
    

    5. Swift Testingを使用してテストを書く

    import Testing
    
    @Test("Sync manager handles missing container")
    func testMissingContainer() async {
        let mockFileSystem = MockFileSystemProvider(containerURL: nil)
        let manager = SyncManager(fileSystem: mockFileSystem)
    
        await #expect(throws: SyncError.containerNotAvailable) {
            try await manager.sync()
        }
    }
    
    @Test("Sync manager reads data correctly")
    func testReadData() async throws {
        let mockFileAccessor = MockFileAccessor()
        mockFileAccessor.files[testURL] = testData
    
        let manager = SyncManager(fileAccessor: mockFileAccessor)
        let result = try await manager.loadData()
    
        #expect(result == expectedData)
    }
    
    @Test("Sync manager handles read errors gracefully")
    func testReadError() async {
        let mockFileAccessor = MockFileAccessor()
        mockFileAccessor.readError = CocoaError(.fileReadCorruptFile)
    
        let manager = SyncManager(fileAccessor: mockFileAccessor)
    
        await #expect(throws: SyncError.self) {
            try await manager.sync()
        }
    }
    

    ベストプラクティス

    • 単一責任:各プロトコルは1つの関心事を処理する——多くのメソッドを持つ「ゴッドプロトコル」を作らない
    • Sendable 一貫性:プロトコルがActor境界をまたいで使用される場合に必要
    • デフォルトパラメーター:本番コードは実際の実装をデフォルトで使用する。テストだけがモックを指定する必要がある
    • エラーのモック:障害パスをテストするために設定可能なエラープロパティを持つモックを設計する
    • 境界のみをモック:外部の依存関係(ファイルシステム、ネットワーク、API)をモックし、内部型はモックしない

    避けるべきアンチパターン

    • すべての外部アクセスをカバーする単一の大きなプロトコルを作成する
    • 外部の依存関係を持たない内部型をモックする
    • 適切な依存性注入の代わりに #if DEBUG 条件文を使用する
    • Actorと組み合わせて使用する際に Sendable 一貫性を忘れる
    • 過度な設計:型が外部の依存関係を持たない場合、プロトコルは必要ない

    使用場面

    • ファイルシステム、ネットワーク、または外部APIに触れるあらゆるSwiftコード
    • 実際の環境では引き起こすことが難しいエラー処理パスをテストする場合
    • アプリ、テスト、SwiftUIプレビューのコンテキストで動作するモジュールを構築する場合
    • Swift並行処理(Actor、構造化並行処理)を採用したテスト可能なアーキテクチャが必要なアプリ

    Alternatives

    Compare before choosing