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

Ios completionHandler不能在Xcode的单元测试中执行,例如异步api-CLGeocoder的reverseGeocodeLocation,ios,xcode,swift,asynchronous,clgeocoder,Ios,Xcode,Swift,Asynchronous,Clgeocoder,我知道CLGeocoder().reverseGeocodeLocation(…)将在另一个线程中执行,因此一旦completionHandler成功从Apple server获得结果,它将在主线程中执行。问题是,当我在单元测试中使用completionHandler时(当我构建框架时),我看不到它发生了什么,但它在应用程序中运行良好。为了简化我的问题,我在单元测试中从代码中提取异步部分,如下所示: func testGeo() { var location = CLLocation(l

我知道CLGeocoder().reverseGeocodeLocation(…)将在另一个线程中执行,因此一旦completionHandler成功从Apple server获得结果,它将在主线程中执行。问题是,当我在单元测试中使用completionHandler时(当我构建框架时),我看不到它发生了什么,但它在应用程序中运行良好。为了简化我的问题,我在单元测试中从代码中提取异步部分,如下所示:

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

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

从Xcode 6开始,苹果公司推出了一款名为XTestExpection的异步测试设备。这使我们能够在超出范围之前等待一段时间。用法非常简单,如下所示:

    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
        }
    }