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()
…
Run a pre-release verification loop for Quarkus builds, tests, scans, and reviews.
Speed up complex tasks with parallel execution while preserving correctness.
Learn practical Kotlin Ktor server patterns for building and testing backend apps.
Extract shared principles from skills and turn them into maintainable rule files.
Coordinate behavior-preserving code refactors with tests, review, and gated commits.
Organize inboxes, draft emails, verify sending, and follow up safely.
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.