如何对其中包含DispatchQueue.main.async的异步代码进行单元测试

时间:2018-04-20 16:15:00

标签: ios swift unit-testing

我在下面写了快速代码

public func authenticateTouchID(completion: @escaping (_ result: Bool, _ error: Error?) -> Void) {
authenticationContext.evaluatePolicy(
  .deviceOwnerAuthenticationWithBiometrics,
  localizedReason: NSLocalizedString("temp", comment: ""),
  reply: { (result, error) -> Void in
    DispatchQueue.main.async {
      guard let error =  error else {
        completion(result, nil)
        return
      }
      completion(result, error)
    }
}
)}

在进行单元测试时,我面临着问题。 这在本地完美运行,但在生成teamcity构建时却失败了。

请告诉我如何对上面的代码进行单元测试?

1 个答案:

答案 0 :(得分:2)

首先让我建议在调用完成处理程序时删除额外的代码。警卫声明是多余的。

public func authenticateTouchID(completion: @escaping (_ result: Bool, _ error: Error?) -> Void) {
authenticationContext.evaluatePolicy(
  .deviceOwnerAuthenticationWithBiometrics,
  localizedReason: NSLocalizedString("temp", comment: ""),
  reply: { (result, error) -> Void in
    DispatchQueue.main.async {
      completion(result, error)
    }
  }
)}

接下来,我建议在队列中传递你想要运行完成...但是默认值为DispatchQueue.main,这样你的应用程序调用站点就不会改变,但是在你的测试代码中你可以传递别的东西。

public func authenticateTouchID(completion: @escaping (_ result: Bool, _ error: Error?) -> Void, onQueue queue: DispatchQueue = DispatchQueue.main) {
authenticationContext.evaluatePolicy(
  .deviceOwnerAuthenticationWithBiometrics,
  localizedReason: NSLocalizedString("temp", comment: ""),
  reply: { (result, error) -> Void in
    queue.async {
      completion(result, error)
    }
  }
)}