completionHandler不能在Xcode的单元测试中执行,例如。异步api - CLGeocoder的reverseGeocodeLocation

时间:2015-05-28 07:39:19

标签: ios xcode swift asynchronous clgeocoder

我理解CLGeocoder()。reverseGeocodeLocation(...)将在另一个线程中执行,因此一旦成功从Apple服务器获取结果,completionHandler将在主线程中执行。问题是当我在单元测试中使用(当我构建框架时)时,我无法看到completionHandler中发生了什么,但它在Application中工作正常。为了简化我的问题,我在单元测试中从我的代码中提取异步部分,如下所示:

func testGeo() {
    var location = CLLocation(latitude: 45.0, longitude: 135.5)
    var semaphore = dispatch_semaphore_create(0)
    println("------fetch----->")
    CLGeocoder().reverseGeocodeLocation(location, completionHandler:{ (placemarks, error) -> Void in
        if error != nil {
            println("[ERROR]: \(error) in getPlacemarkFromLocation")
        }

        if placemarks.count > 0 {
            println("[SUCCESS] get the placemark!")
            let pm = placemarks[0] as! CLPlacemark
            self.displayLocationInfo(pm)
        } else {
            println("[ERROR] get 0 placemarks in getPlacemarkFromLocation")
        }
        dispatch_semaphore_signal(semaphore)
    })
    println("------wait--- -->")
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
}

当我进行单元测试时,似乎没有执行completionHandler,因为没有什么要在控制台中打印。每次我使用异步api时,我都无法在单元测试中成功获得返回值。我需要使用单元测试来确保我的框架的所有管道都能正常工作。这会让我发疯...我怎么能解决这个问题呢?非常感谢:)

1 个答案:

答案 0 :(得分:0)

问题是因为测试函数在完成处理程序完成之前退出。

从Xcode 6开始,Apple发布了一个名为 XCTestExpectation 的异步测试工具。这件事使我们能够在超出范围之前等待一段时间。用法很简单:

    let expect = self.expectationWithDescription("exp")
    sc.asyncCall(para) { (data, error) in

        XCTAssertNotNil(data)

        expect.fulfill()
    }

    self.waitForExpectationsWithTimeout(1) { (error) in
        guard error == nil else {
            XCTAssert(false)
            NSLog("Timeout Error.")
            return
        }
    }