加入我们在 Slack 上的社区! -> 邀请链接在这里
- 易于使用的语法,充分利用自动完成的全功能,这使得编写测试更加容易和快捷
- 我们确实支持泛型
- 模拟实现生成
- 指定模拟将返回什么(给出)的方式
- 为不同属性指定不同返回值的能力
- 记录模拟返回值的序列
- 验证是否在模拟上调用了一个方法
- 检查具有指定属性的方法调用
- 它可以在真实设备上工作
重要!!! 版本 4.1.x
命令行界面 CLI 已回归主(此)仓库。该仓库中的 CLI 将至少支持到版本 5.0.0。
版本 4.0.x
当前版本有多个重大改动。它移除了过时的方法(可能会破坏),并弃用了将 CLI 放入新 仓库 的做法。
SwiftyPrototype 也被提取到了独立的库中。没有更多的编译标志,因此如果您曾依赖于带有 -DMockyCustom
的 SwiftyMocky,您将需要切换到 SwiftyPrototype
。
我们认为当前版本是稳定的。我们正在转向使用新的 Mockfile,但仍然支持之前的配置格式。库支持 Swift 4.1, 4.2, 5.0, 5.1.2 和 Sourcery 1.0.x。
虽然技术上可以在 Linux 目标上集成 SwiftyMocky,但目前还没有 Mock 生成功能。只要您的机器在 Mac 上生成 Mock 没问题,您可以通过 SwiftPM 使用 SwiftyMokcy 运行时。
从 3.2.0 及以下版本迁移
迁移不是必需的,您可以像以前一样继续使用 SwiftyMocky。在 遗留下来的配置 在 指南部分 中有描述。
尽管如此,我们还是鼓励您尝试新的 CLI 并提供反馈。我们认为这将使使用和设置 SwiftyMocky 更为简单。如果您有现有的配置,请按照此 指南 安装 CLI 并尝试。
> swiftymocky migrate
入门指南
1. 集成 SwiftyMocky
SwiftyMocky 通过 CocoaPods 提供使用。要安装它,只需将以下行添加到您的 Podfile
pod "SwiftyMocky"
使用项目目录中的 CLI 工具
# To setup initial Mockfile
% ./Pods/SwiftyMocky/bin/swiftymocky init
# To generate mocks
% ./Pods/SwiftyMocky/bin/swiftymocky generate
要安装,将以下内容添加到您的 Cartfile
github "MakeAWishFoundation/SwiftyMocky"
然后执行 carthage update
对于 Carthage,需要一些额外的步骤
您需要安装 CLI 生成模拟 - 查看 [安装][#installation]
将 SwiftyMocky 添加到您的 Package.swift 依赖项
dependencies: [
.package(url: "https://github.com/MakeAWishFoundation/SwiftyMocky", from: "4.1.0-pre"),
]
您需要安装 CLI 生成模拟 - 查看 [安装][#installation]
注意:有关将 SwiftyMocky 集成到单元测试工具以及作为原型化框架的示例,请参阅此处:https://github.com/MakeAWishFoundation/SM-Integration-Tests
2. 安装 SwiftyMocky CLI
> brew install mint
> mint install MakeAWishFoundation/SwiftyMocky-CLI
> marathon install MakeAWishFoundation/SwiftyMocky-CLI
Make:
从 https://github.com/MakeAWishFoundation/SwiftyMockyCLI 克隆并运行根目录下的 make
。
3. 生成模拟
为即将进行模拟的协议标注,使它们遵循 AutoMockable
协议,或在源代码中定义上方添加注解注释。
模拟从您的项目根目录生成,基于 Mockfile 内的配置。
> path/to/swiftymocky setup # if you don't have a Mockfile yet
> path/to/swiftymocky doctor # validate your setup
> path/to/swiftymocky generate # generate mocks
如果您不想迁移到我们的 CLI 并更喜欢使用“原始”Sourcery,请参阅文档中的这部分。
用法
1. 模拟的标记协议
在您的项目中创建一个“虚拟”协议,例如: protocol AutoMockable { }
将此协议用于您想要实际模拟的每个协议。
protocol ToBeMocked: AutoMockable {
// ...
}
或者,使用sourcery注解将打算模拟的协议标记如下
//sourcery: AutoMockable
protocol ToBeMocked {
// ...
}
或者用它来处理协议组合
typealias ToBeMocked = OneProtocol & TwoProtocols & AutoMockable
在源目录中的所有具有此注解的协议都将添加到Mock.generated.swift
2. 模拟方法返回值 - 给定
所有模拟都有给定方法(可以通过实例方法或全局函数访问),使用易于理解的语法,允许为给定方法指定应返回的值(基于指定属性)。
所有协议方法都很好地整理到给定中,具有匹配的签名。这允许使用自动完成(只需要输入“.”)来查看所有模拟的协议方法,并指定其返回值。
所有方法属性都包含在Parameter
枚举中,允许在“any”和“value”之间进行选择,为模拟行为提供极大的灵活性。请考虑以下
Given(mock, .surname(for name: .value("Johnny"), willReturn: "Bravo"))
Given(mock, .surname(for name: .any, willReturn: "Kowalsky"))
print(mock.surname(for: "Johny")) // Bravo
print(mock.surname(for: "Mathew")) // Kowalsky
print(mock.surname(for: "Joanna")) // Kowalsky
在3.0版本中,我们引入了序列和策略,以更好地控制模拟行为。
Given(mock, .surname(for name: .any, willReturn: "Bravo", "Kowalsky", "Nguyen"))
print(mock.surname(for: "Johny")) // Bravo
print(mock.surname(for: "Johny")) // Kowalsky
print(mock.surname(for: "Johny")) // Nguyen
print(mock.surname(for: "Johny")) // and again Bravo
// ...
有关更多详细信息,请参阅完整文档。
3. 检查方法、子脚本和属性的调用 - 验证
所有模拟都有验证方法(可以通过实例方法或全局函数访问),使用简单易用的语法,允许验证方法是否在模拟上调用以及调用的次数。它还提供了一个方便的方式来指定方法属性是否重要(以及哪些属性)。
所有协议方法都很好地组织到Verify
中,具有匹配的签名。这样,就可以使用自动完成来查看所有模拟的协议方法(只需输入“.”),并指定要验证的方法。
所有方法属性都封装在Parameter
枚举中,允许在“any”、“value”和“matching”之间进行选择,为测试提供极大的灵活性。请考虑以下
// inject mock to sut. Every time sut saves user data, it should trigger storage storeUser method
sut.usersStorage = mockStorage
sut.saveUser(name: "Johny", surname: "Bravo")
sut.saveUser(name: "Johny", surname: "Cage")
sut.saveUser(name: "Jon", surname: "Snow")
// check if Jon Snow was stored at least one time
Verify(mockStorage, .storeUser(name: .value("Jon"), surname: .value("Snow")))
// storeUser method should be triggered 3 times in total, regardless of attributes values
Verify(mockStorage, 3, .storeUser(name: .any, surname: .any))
// storeUser method should be triggered 2 times with name Johny
Verify(mockStorage, 2, .storeUser(name: .value("Johny"), surname: .any))
// storeUser method should be triggered at least 2 times with name longer than 3
Verify(mockStorage, .moreOrEqual(to: 2), .storeUser(name: .matching({ $0.count > 3 }), surname: .any))
对于验证,您可以使用Count
来指定预期触发的次数。计数可以是显式值,如1
、2
、...,或者更描述性和灵活的表达方式,如.never
、more(than: 1)
等。
从SwiftyMocky 3.0开始,可以将Given
用于属性,并执行Verify
,无论是获取还是设置操作。
mock.name = "Danny"
mock.name = "Joanna"
print(mock.name)
// Verify getter:
Verify(mock, 1, .name)
// Verify setter:
Verify(mock, 2, .name(set: .any))
Verify(mock, 1, .name(set: .value("Danny")))
Verify(mock, .never, .name(set: .value("Bishop")))
4. 当调用占位方法时采取行动 - 执行
所有模拟都具有执行方法(既可作为实例方法也可以作为全局函数访问),具有易于使用的语法,允许指定在调用模拟方法时将执行的闭包。
它使用与given相同的参数包装功能,因此您可以为不同的属性设置指定不同的执行情况。
当与基于完成块的方案一起使用时非常方便。
示例
// Perform allows to execute given closure, with all the method parameters, as soon as it is being called
Perform(mock, .methodThatTakesCompletionBlock(completion: .any, perform: { completion in
completion(true,nil)
}))
文档
完整的文档可以在以下位置查阅:这里,也可以通过docs目录访问。
指南 - 目录
变更日志可在以下地址查阅:这里
全部支持的功能
使用示例
要查看更多示例,请查看我们的示例项目,或在指南中的示例部分。
要运行示例项目,首先从示例目录中克隆仓库,然后运行pod install
。
要触发模拟生成,请从根目录运行rake mock
或swiftymocky generate
(如果已安装CLI)。
路线图
- 优雅地模拟协议
- 生成模拟模板
- 示例项目
- 使用变量模拟协议
- 生成不存在名称冲突的方法签名
- 使用单元测试覆盖95%的框架代码库
- 使用文档覆盖95%的框架代码库
- 为模板添加单元测试
- 支持tvOS、Linux和MacOS
- Carthage支持
- 下标支持
- 将模拟返回值作为序列
- 简化配置过程的工具
贡献者
- Przemysław Wośko, [email protected]
- Andrzej Michnia, [email protected]
许可协议
SwiftyMocky能够在MIT许可下使用。更多信息请参阅LICENSE文件。