MockableMacros


💻 🤲 🌓 ⚒️
用于使用宏轻松模拟对象的 SPM 包
只需将 @Mockable 属性添加到您的协议,然后使用新的类即可。

用法

只需将属性添加到您的协议,如下所示

  @Mockable
  public protocol CarProtocol {
    var isStarted: Bool { get set }
  
    func startEngine(full: Bool) async throws -> Bool
    func startEngine(turnOn: Bool, completion: @escaping () -> Void)
    func startEngine(completion: @escaping (Int) -> Void)
    func startEngine(result: Int, completion: @escaping (Result<Int, Never>) -> Void)
  }

这将生成 CarProtocolMockable 类,其中包含变量和函数,并带有额外的变量以方便测试。

示例
public final class CarProtocolMockable: CarProtocol {

public init() {
}

// MARK: - Variables

public var isStarted: Bool {
    get {
        return underlyingIsStarted
    }
    set(value) {
        underlyingIsStarted = value
    }
}

public var underlyingIsStarted: Bool!

// MARK: - Functions

// `startEngineFull` mock block

public var startEngineFullCallsCount: Int = 0
public var startEngineFullCalled: Bool {
  return startEngineFullCallsCount > 0
}
public var startEngineFullError: MockError?
public var startEngineFullResponse: Bool?

public func startEngine(full: Bool) async throws -> Bool {
  startEngineFullCallsCount += 1
  if let error = startEngineFullError {
      throw error
  }
  return startEngineFullResponse!
}

// `startEngineTurnOnCompletion` mock block

  public var startEngineTurnOnCompletionCallsCount: Int = 0
public var startEngineTurnOnCompletionCalled: Bool {
  return startEngineTurnOnCompletionCallsCount > 0
}

public var startEngineTurnOnCompletionResponse: ((Bool, @escaping () -> Void) -> Void)?

public func startEngine(turnOn: Bool, completion: @escaping () -> Void) {
  startEngineTurnOnCompletionCallsCount += 1

  startEngineTurnOnCompletionResponse?(turnOn, completion)
}

// `startEngineCompletion` mock block

  public var startEngineCompletionCallsCount: Int = 0
public var startEngineCompletionCalled: Bool {
  return startEngineCompletionCallsCount > 0
}

public var startEngineCompletionResponse: ((@escaping (Int) -> Void) -> Void)?

public func startEngine(completion: @escaping (Int) -> Void) {
  startEngineCompletionCallsCount += 1

  startEngineCompletionResponse?(completion)
}

// `startEngineResultCompletion` mock block

  public var startEngineResultCompletionCallsCount: Int = 0
public var startEngineResultCompletionCalled: Bool {
  return startEngineResultCompletionCallsCount > 0
}

public var startEngineResultCompletionResponse: ((Int, @escaping (Result<Int, Never>) -> Void) -> Void)?

public func startEngine(result: Int, completion: @escaping (Result<Int, Never>) -> Void) {
  startEngineResultCompletionCallsCount += 1

  startEngineResultCompletionResponse?(result, completion)
}
}

动机

这是 Sourcery AutoMockable 的替代解决方案。我希望在不同的项目中创建 mock 类,因为我们的产品是使用 tuist 构建的。我遇到了问题,Sourcery 只能在一个文件夹中生成文件,这对我来说是不可接受的。因此,我不得不转向 Swift 的新功能并研究 Macros。

替代方案