
Swift Protocol Di Testing
Structure Swift apps with protocol-based DI so solo builders can mock I/O and run deterministic Swift Testing without hitting real disks or networks.
Overview
Swift Protocol DI Testing is an agent skill most often used in Build (also Ship) that shows how to hide file, network, and API access behind focused Swift protocols with mocks for Swift Testing.
Install
npx skills add https://github.com/affaan-m/everything-claude-code --skill swift-protocol-di-testingWhat is this skill?
- Defines small, focused Sendable protocols (FileSystemProviding, FileAccessorProviding, BookmarkStorageProviding) for one
- Pairs production default implementations with in-memory mocks for Swift Testing
- Supports testing error paths and sandbox/bookmark flows without real I/O
- Aligns with Swift concurrency (actors, Sendable) for app, test, and SwiftUI preview targets
- Enables deterministic unit tests that run in CI without flaky network or disk side effects
- Three example protocol families: file system, file accessor, and bookmark storage
Adoption & trust: 4.5k installs on skills.sh; 210k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your Swift code talks directly to disks and networks, so you cannot exercise error paths or run fast, deterministic tests in CI.
Who is it for?
Indie iOS/macOS builders adding Swift Testing to modules that use sandboxes, bookmarks, or network clients.
Skip if: One-off SwiftUI views with no external dependencies, or teams that already standardize on a full DI container and do not want protocol-first patterns.
When should I use this skill?
Writing Swift that accesses file system, network, or external APIs; testing error paths without real failures; cross-environment modules with Swift concurrency.
What do I get? / Deliverables
External dependencies sit behind injectable protocols with production and mock implementations, so tests run without I/O and architecture stays preview-friendly.
- Focused dependency protocols and production conformances
- Mock providers for Swift Testing
- Tests covering success and error paths without I/O
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Canonical shelf is Build because the skill guides architecture and dependency boundaries while you write Swift modules, not only at QA time. Integrations fits abstracting file system, network, bookmarks, and external APIs behind small protocols—the glue between your app and the outside world.
Where it fits
Refactor a document picker service behind FileAccessorProviding before adding cloud sync.
Wrap URLSession in a narrow protocol so API clients compile in app and test targets.
Add Swift Testing cases that throw on mock read failures without touching the real disk.
Review whether new Swift modules still depend on concrete FileManager instead of protocols.
How it compares
A architecture-and-testing pattern skill, not a test runner or XCTest cheat sheet.
Common Questions / FAQ
Who is swift-protocol-di-testing for?
Solo and small-team Swift developers who want testable services without heavyweight DI frameworks.
When should I use swift-protocol-di-testing?
During Build when defining file or network access, and during Ship when expanding Swift Testing coverage for failure and sandbox paths.
Is swift-protocol-di-testing safe to install?
It is documentation-only procedural guidance; review the Security Audits panel on this page before trusting any third-party skill package.
SKILL.md
READMESKILL.md - Swift Protocol Di Testing
# Swift Protocol-Based Dependency Injection for Testing Patterns for making Swift code testable by abstracting external dependencies (file system, network, iCloud) behind small, focused protocols. Enables deterministic tests without I/O. ## When to Activate - Writing Swift code that accesses file system, network, or external APIs - Need to test error handling paths without triggering real failures - Building modules that work across environments (app, test, SwiftUI preview) - Designing testable architecture with Swift concurrency (actors, Sendable) ## Core Pattern ### 1. Define Small, Focused Protocols Each protocol handles exactly one external concern. ```swift // 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. Create Default (Production) Implementations ```swift 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. Create Mock Implementations for Testing ```swift 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. Inject Dependencies with Default Parameters Production code uses defaults; tests inject mocks. ```swift 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. Write Tests with Swift Testing ```swift import Testing @Test("Sync manager handles missing container") func testMissingContainer() async { let mockFileSystem = MockFileSystemProvider(containerURL: nil) let manager = SyncManager(fileSystem: mockFileSystem) await #expect(t