Skills Plugins MCP Prompt Model 博客 我的中心
开发编程 #api #testing

swift-protocol-di-testing

Protocol-based dependency injection for testable Swift code — mock file system, network, and external APIs using focused protocols and Swift Testing.

DeepseekModel 官方收录技能 质量 优秀 · 90 v1.0.0

获取

https://deepseekmodel.com/api/download.php?id=affaan-m-ecc-kiro-skills-swift-protocol-di-testing-skill-md&format=skill
下载 .skill 标准格式,含 system_prompt 与 model_config,导入任意 Agent 框架即可使用
.skill 文件中 system_prompt 字段的实际内容。
name swift-protocol-di-testing description Protocol-based dependency injection for testable Swift code — mock file system, network, and external APIs using focused protocols and Swift Testing. origin ECC 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. // 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 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 /// NOTE: Not thread-safe. Use only in single-threaded test contexts. 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. 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 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() } } Best Practices Single Responsibility : Each protocol should handle one concern — don't create "god protocols" with many methods Sendable conformance : Required when protocols are used across actor boundaries Default parameters : Let production code use real implementations by default; only tests need to specify mocks Error simulation : Design mocks with configurable error properties for testing failure paths Only mock boundaries : Mock external dependencies (file system, network, APIs), not internal types Anti-Patterns to Avoid Creating a single large protocol that covers all external access Mocking internal types that have no external dependencies Using #if DEBUG conditionals instead of proper dependency injection Forgetting Sendable conformance when used with actors Over-engineering: if a type has no external dependencies, it doesn't need a protocol When to Use Any Swift code that touches file system, network, or external APIs Testing error handling paths that are hard to trigger in real environments Building modules that need to work in app, test, and SwiftUI preview contexts Apps using Swift concurrency (actors, structured concurrency) that need testable architecture
Agent 识别该技能的关键词,点击任意一个即可复制。

该技能未提供触发词。

下载的 .skill 包内含以下字段。
字段 说明
format格式标识(skill/v1)
skill_id技能唯一 ID
name技能名称
version版本号
description技能描述
category所属分类(数组)
trigger_words触发词列表
tags标签列表
source来源标识
source_url来源链接(本页地址)
exported_at导出时间(每次下载生成)
system_prompt系统提示词正文
model_config模型参数:provider / model / temperature / max_tokens / top_p
examples示例
install_guide各平台导入说明(Coze / Dify / Claude / 自定义框架)
同一份技能可按不同平台格式导出。
.skill 标准格式,含 system_prompt 与 model_config,导入任意 Agent 框架即可使用 下载
.skillpro 增强格式,额外含脚本 / 工具 / 依赖 / 钩子占位 下载
.json 纯 JSON 导出,只含 system_prompt 与模型参数 下载
Coze 带 frontmatter 的 Markdown,Coze 平台导入用 下载
Dify Dify DSL,创建应用后直接导入 下载

每日精选 Skill 推荐,免费送到你邮箱

输入邮箱,每天接收一个精选 AI Agent 技能推荐。完全免费,持续更新。

提交后我们会发送一封确认邮件,点击邮件里的链接才会开始收信。

完全免费,取消任意时间。我们不会发送垃圾邮件。