Build testable Swift code with protocol-based dependency injection and focused mocks.
Copy the install command and let the AI configure it · recommended for beginners
Please install the "swift-protocol-di-testing" skill from askskill: 1. Download https://raw.githubusercontent.com/affaan-m/ECC/main/skills/swift-protocol-di-testing/SKILL.md 2. Save it as ~/.claude/skills/swift-protocol-di-testing/SKILL.md 3. Reload skills and tell me it's ready
Show in Swift how to decouple file reading logic from a concrete FileManager implementation, define a minimal protocol and inject the dependency, then write unit tests with Swift Testing including one successful read mock and one failure mock.
Provides a protocol-based file system abstraction, injectable app logic, and tests using mocks for success and failure scenarios.
Design a Swift networking example that uses a protocol to abstract the request-sending layer so business logic does not depend directly on URLSession. Then provide Swift Testing code for mock success, error, and timeout scenarios.
Returns a replaceable networking protocol, production implementation guidance, and unit tests covering multiple response cases.
Demonstrate how to define single-responsibility protocols for an external API service in Swift and use dependency injection to make a ViewModel testable. Include a mock service, the ViewModel implementation, and corresponding Swift Testing tests.
Delivers focused API protocol design, a testable ViewModel structure, and mock-based test examples.
Patterns for making Swift code testable by abstracting external dependencies (file system, network, iCloud) behind small, focused protocols. Enables deterministic tests without I/O.
Each protocol handles exactly one external concern.
// 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?
}
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)
}
}
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
}
}
Production code uses defaults; tests inject mocks.
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...
}
}
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()
…
Build polished React and Next.js animations with reusable production-ready patterns.
Design security and risk controls for autonomous trading agents with transaction authority
Write and review React 18/19 components using modern best practices.
Get production-ready MySQL and MariaDB schema, query, and operations patterns.
Verify Laravel projects with environment checks, tests, security scans, and release readiness.
Audit Claude skills and commands with quick scans or full stocktakes.
Test and validate glasses features without physical hardware using MockDeviceKit.
Identify test anti-patterns and improve tests without polluting production code.
Helps developers migrate Swift code using the concurrency migration guide.
Helps developers avoid common testing anti-patterns and write more reliable tests.
Build high-quality Kotlin tests with Kotest, MockK, coroutines, and coverage.
Provides curated, up-to-date SwiftUI components for AI coding agents.