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()
…
Turn a plan document into stepwise /orchestrate prompts and agent chains.
Handle customs documents, tariff classification, screening, and duty optimization decisions.
Apply Laravel security best practices for auth, vulnerabilities, APIs, and deployment.
Refine retrieved context iteratively to improve subagent understanding and output quality.
Design consistent, production-ready REST APIs with practical conventions and patterns.
Design and choose autonomous Claude Code loop architectures and implementation patterns.
Improve Swift tests, migrate from XCTest, and modernize testing architecture.
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.
Fetch Apple docs, analyze Xcode errors, and verify Swift Evolution proposals.
Helps developers avoid common testing anti-patterns and write more reliable tests.