我理解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时,我都无法在单元测试中成功获得返回值。我需要使用单元测试来确保我的框架的所有管道都能正常工作。这会让我发疯...我怎么能解决这个问题呢?非常感谢:)
答案 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
}
}