【问题标题】:API violation - multiple calls made to -[XCTestExpectation fulfill]API 违规 - 多次调用 -[XCTestExpectation 完成]
【发布时间】:2015-03-27 04:47:59
【问题描述】:

我正在用 Swift 编写我的第一个集成测试。

我正在尝试检查特定网址中是否存在图像。

我想执行一个头部请求并检查响应的状态码。

我不断收到错误:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'API violation - multiple calls made to -[XCTestExpectation fulfill].

我尝试将期望设为弱变量。

我有以下代码/测试:

func testAndroidImagesExist() {
 weak var expectation: XCTestExpectation?
 expectation =  expectationForNotification(kBaoNotification_ManifestImportCompleted, object: nil) { (notification: NSNotification!) -> Bool in

 let userInfo: NSDictionary = notification.userInfo!
 var titles = userInfo.valueForKey("titles") as? NSArray
 titles?.enumerateObjectsUsingBlock({ (t: AnyObject!, idx: Int, stop: UnsafeMutablePointer<ObjCBool>) -> Void in
  let title = t as NSDictionary

  let titleLabel = title.valueForKey("title") as String
  let parameters = title.valueForKey("parameters") as NSDictionary
  let androidImageUrl = parameters.valueForKey("android_logo_url") as String
  var androidRequest = NSMutableURLRequest(URL: NSURL(string: androidImageUrl)!)
  androidRequest.HTTPMethod = "HEAD"
  var androidResponse: NSURLResponse?
  var androidData = NSURLConnection.sendSynchronousRequest(androidRequest, returningResponse: &androidResponse, error: nil)
  var androidHttpResponse = androidResponse as? NSHTTPURLResponse

  if androidHttpResponse != nil {
   if androidHttpResponse!.statusCode == 404 {
    XCTFail("Android image not found for title \(titleLabel)")
   }
  } else {
   XCTFail("No response from android image for title \(titleLabel)")
  }
 })
 expectation?.fulfill()
 return true
}
 waitForExpectationsWithTimeout(10, handler: { (error: NSError!) -> Void in
  if (error != nil) {
   XCTFail("Timeout error: \(error)")
  }
 }) 
}

有什么想法吗?

【问题讨论】:

  • 您找到解决方案了吗?我的集成测试在本地运行,但是当我尝试在构建服务器上运行它们时出现此错误。
  • 我无法理解如何执行一次甚至调用一次。您正在创建一个expectationForNotification,但是在您的代码中的哪个位置生成了预期的通知?

标签: swift xctest


【解决方案1】:

我遇到了同样的问题(在 Objective-C 中);我在完成之前添加了一个空 ptr 检查,它似乎对我来说很稳定。

【讨论】:

    【解决方案2】:

    我建议处理多次出现的期望的最佳方法是在完成后将期望变量设置为 nil。然后,后续调用将被忽略。

    目标-C:

    // Fulfill and remove. Subsequent messages to nil are ignored.
    [multiEx fulfill];
    multiEx = nil;`
    

    斯威夫特:

    // Fulfill and remove. Optional chaining ends execution on nil.
    var multiEx:XCTestExpectation? = expectationWithDescription("multiEx")
    ...
    multiEx?.fulfill() 
    multiEx = nil
    

    【讨论】:

    • 你也可以将 nil 代码放入 teardown 中 override func tearDown() { // 在这里放入 teardown 代码。在调用类中的每个测试方法之后调用此方法。 super.tearDown() 期望 = nil }
    【解决方案3】:

    我已经为此苦苦挣扎了一段时间,投票最多的答案对我不起作用。主要区别在于异步响应来自委托,而不是闭包。

    对我有用的是在第一次调用 'fulfill' 后将我的委托设置为 nil。

    希望对某人有所帮助。

    【讨论】:

      【解决方案4】:

      使用expectation.fulfillmentcount,您将能够多次实现期望

      func testMethod() {
      let exp = expectation(description:)
      let exp.fullfillmentCount = INT
      exp.fullfill x called == exp.fullfillmentCount -> testpass
      }
      

      【讨论】:

        猜你喜欢
        • 2014-09-29
        • 2021-12-06
        • 2018-09-26
        • 2015-02-06
        • 1970-01-01
        • 1970-01-01
        • 2012-09-18
        • 1970-01-01
        • 2017-07-04
        相关资源
        最近更新 更多