什么是Sourcery?
Sourcery 是当下最流行的 Swift 代码生成工具之一。其背后使用了 SwiftSyntax[1],旨在通过自动生成样板代码来节省开发人员的时间。Sourcery 通过扫描一组输入文件,然后借助模板的帮助,自动生成模板中定义的 Swift 代码。
示例
考虑一个为摄像机会话服务提供公共 API 的协议:
代码语言:javascript复制protocol Camera {
func start()
func stop()
func capture(_ completion: @escaping (UIImage?) -> Void)
func rotate()
}
当使用此新的 Camera service
进行单元测试时,我们希望确保 AVCaptureSession
没有被真的创建。我们仅仅希望确认 camera service
被测试系统(SUT)正确的调用了,而不是去测试 camera service
本身。
因此,创建一个协议的 mock 实现,使用空方法和一组变量来帮助我们进行单元测试,并断言(asset
)进行了正确的调用是有意义的。这是软件开发中非常常见的一个场景,如果你曾维护过一个包含大量单元测试的大型代码库,这么做也可能有点乏味。
好吧~不用担心!Sourcery 会帮助你!⭐️ 它有一个叫做 AutoMockable[2] 的模板,此模板会为任意输入文件中遵守 AutoMockable
协议的协议生成 mock 实现。
注意:在本文中,我扩展地使用了术语
Mock
,因为它与 Sourcery 模板使用的术语一致。Mock
是一个相当重载的术语,但通常,如果我要创建一个 双重测试[3],我会根据它的用途进一步指定类型的名称(可能是Spy
、Fake
、Stub
等)。如果您有兴趣了解更多关于双重测试的信息,马丁·福勒(Martin Fowler)有一篇非常好的文章,可以解释这些差异。
现在,我们让 Camera
遵守 AutoMockable
。该接口的唯一目的是充当 Sourcery 的目标,从中查找并生成代码。
import UIKit
// Protocol to be matched
protocol AutoMockable {}
public protocol Camera: AutoMockable {
func start()
func stop()
func capture(_ completion: @escaping (UIImage?) -> Void)
func rotate()
}
此时,可以在上面的输入文件上运行 Sourcery 命令,指定 AutoMockable
模板的路径:
sourcery --sources Camera.swift --templates AutoMockable.stencil --output .