StubKit
智能占位符系统。
安装
使用 Carthage
github "kateinoigakukun/StubKit"
使用 CocoaPods
pod "StubKit", :git => "https://github.com/kateinoigakukun/StubKit.git"
用法
入门
您可以使用一行代码实例化任何类型的 Decodable。
import StubKit
// Codable struct
struct User: Codable {
let id: Int
let name: String
let sex: Sex
}
let stubUser = try Stub.make(User.self)
// User(id: 1234, name: "This is Stub String", sex: .female)自定义属性
即使属性是被定义为 let,也可以自定义。
let maleUser = try Stub.make(User.self) {
$0.set(\.sex, value: .male)
}
// User(id: 1234, name: "This is Stub String", sex: .male)使用 Stubbable
如果您想自定义默认的 stub 值,请遵守 Stubbable。
extension String: Stubbable {
static func stub() -> String {
return "This is custommized Stub String"
}
}
let stubUser = try Stub.make(User.self)
// User(id: 1234, name: "This is customized Stub String", sex: .female)高级用法
struct RandomIntStubProvider: StubProvider {
func stub<T>(of type: T.Type) -> T? {
if type is Int.Type {
return Int.random(in: 0..<100) as? T
}
return nil
}
}
let userStub = Stub(type: User.self, provider: [RandomIntStubProvider()])
try userStub.make() // User(id: 97)
try userStub.make() // User(id: 54)
try userStub.make() // User(id: 12)需要将非最终类作为 Stubbable 使之遵守?
通过定义 UnsafeStubbable 可以将其设置为 Stubbable。
public protocol UnsafeStubbable: Stubbable {
associatedtype Target = Self
static func unsafeStub() -> Target
}
extension UnsafeStubbable {
public static func stub() -> Self {
return unsafeStub() as! Self
}
}
extension UIImage: UnsafeStubbable {
public static func unsafeStub() -> UIImage {
return #imageLiteral(resourceName: "dummy")
}
}它是如何工作的
StubKit 主要使用两种技术。
- 使用
Decoder协议进行遍历。 - 使用不可变的
KeyPath注入值。 - 使用
Self实现存在类型。
使用 Decoder 协议遍历结构体
Swift 有 Decodable 协议,如果一个类型遵循 Decodable,Swift 编译器会生成一些代码来内部解码。因此,我们可以在没有任何配置的情况下将 JSON 解码为 Swift 结构体。StubKit 使用此系统通过 Decoder 构建实例。Decoder 是一个协议,它可以通过键或索引提供值,就像 JSONDecoder。如果我们传递一个递归提供占位符值的 Decoder,我们就可以实例化任何类型的 Decodable 实例。
使用非可变 KeyPath 注入值
我知道这是理所当然的,但 Swift 无法修改用 let 定义的属性。但 Swift 有 MemoryLayout<T>.offset,它提供属性从其地址的偏移量。所以实际上在内存中我们可以修改 let 属性。
使用 Self 的存在类型
具有 associatedtype 或使用 Self 类型的协议不能是存在类型。但将 Self 用于方法的返回类型仅适用于 Swift4.2。(我认为将 Self 用于获取器类型也应该可用。)这项技术使 Stubbable 类型安全。
