自动测试数据 (Autofixtures)

CI

什么是自动测试数据 (Autofixtures)?

自动测试数据 (Autofixtures) 是一个实用工具库,可以帮助您为测试套件创建模型。 使用 Autofixtures,您无需编写样板代码来创建模型。

为什么要使用它?

减少编写乏味代码的时间,将更多时间用于编写重要的代码。

它是如何工作的?

Autofixtures 基于 Decodable 协议,以及 Swift 编译器自动合成初始化器的事实。 如果您的模型符合 Decodable,它就已经支持 Autofixtures。

动机

在测试或开发过程中,我们通常需要创建模拟模型(测试数据)来作为参数传递。
这些模型往往变得非常复杂,每次创建都很麻烦,因此您可能会提出一个静态方法来创建模型。
例如

struct User {
  let id: Int
  let name: String
  let email: String
  struct Address {
    let road: String
    let building: String
  }
  let address: Address
}

您可以想出类似这样的东西。

extension User {
  static func fixture(id: Int = 11,
                      name: String = "fix",
                      email: String = "fix",
                      address: Address = .fixture()) -> User {
    return User(id: id,
                name: name,
                email: email,
                address: address)
  }
}

extension Address {
  static func fixture(road: String = "fix",
                      building: String = "fix") -> Address {
    return Address(road: road,
                   building: building)
  }
}

这比每次都内联创建模型要好得多,但它是大量的样板代码,每次我们更改模型时都需要编译和维护。

用法

基本用法

使用 Autofixtures,您所需要做的就是使您的模型符合 Decodable(如果尚未符合),并导入 Autofixtures。

extension User: Decodable {}

let fixture = User.fix

设置器

设置一个值

extension User: Decodable {}

let fixture = User.fix.set(\.address.road, "Abbey Road")

自定义测试数据

使您的模型符合 Autofixtures。 重写协议并提供新的默认值。
使用 .fixDecoded 静态变量以避免无限递归。

extension User: Override {
  static var fixOverride = User.fixDecoded.set(\.address.road, "Abbey Road")
}
let fixture = User.fix

枚举 (Enums)

CaseIterable 枚举从 .fix 返回第一个 case,但它们需要符合 Override 协议。

enum Enum: String, Decodable, CaseIterable {
    case one
    case two
}

extension Enum: Override {}

具有关联值的枚举 (Enums with associated values)

具有关联值的枚举需要提供 override。

enum EnumWithValue: Decodable, Equatable, Override {
    case value(Simple)

    static let fixOverride: EnumWithValue = .value(.fix)
}

可选类型 (Optionals)

可选类型默认返回 nil。

闭包 (Closures)

/// Closure wrapper for decodable support
struct Closure<A,B>: Decodable {
    var closure: (A) -> B

    init(from decoder: Decoder) throws {
        self.closure = { a in fatalError() }
    }
}

/// Example of setting up default for closure
extension Closure: Override where A == Void, B == Int {
    static var fixOverride: Closure<(), Int> = .fixDecoded
        .set(\.closure, { return 9 })
}

安装

您可以通过将 Autofixtures 添加为包依赖项来将其添加到 Xcode 项目。

https://github.com/kkivan/autofixtures

如果您想在 SwiftPM 项目中使用 Autofixtures,只需将其添加到 Package.swift 中的 dependencies 子句即可。

dependencies: [
  .package(url: "https://github.com/kkivan/autofixtures", from: "0.0.5")
]