Xcode XCTest:如何嵌套异步调用(又称“如何避免XCTest API冲突”)
我觉得我有一个很常见的问题,但不知何故错过了关于最佳实践的备忘录。我想知道如何在XCTest中嵌套异步调用 我正试图通过基于Alamofire的RESTAPI在XCTest中测试/清理一些记录。我首先执行get,然后当完成处理程序启动时,我尝试循环返回的记录,对每个记录调用异步删除 第一个/明显的问题是,如果我使用XTest Expections,我会得到一个错误,因为我必须在初始外部get之后等待,然后尝试必须等待后续的删除调用,所以我无法为删除创建Expection,因为此时我正在等待get完成:Xcode XCTest:如何嵌套异步调用(又称“如何避免XCTest API冲突”),xcode,swift,asynchronous,alamofire,xctest,Xcode,Swift,Asynchronous,Alamofire,Xctest,我觉得我有一个很常见的问题,但不知何故错过了关于最佳实践的备忘录。我想知道如何在XCTest中嵌套异步调用 我正试图通过基于Alamofire的RESTAPI在XCTest中测试/清理一些记录。我首先执行get,然后当完成处理程序启动时,我尝试循环返回的记录,对每个记录调用异步删除 第一个/明显的问题是,如果我使用XTest Expections,我会得到一个错误,因为我必须在初始外部get之后等待,然后尝试必须等待后续的删除调用,所以我无法为删除创建Expection,因为此时我正在等待get
func deleteAllFoos() {
let expectation = expectationWithDescription("deleteAllFoos")
var foos:[Foo]!
Api.foos({ i, f in
foos?.append(f) },
count: { c in
foos = [Foo]()
return c },
success: { [unowned self] in
for f in foos {
let deleteExpectation = self.expectationWithDescription("\(f.id)")
Api.fooDelete(f,
success: {
deleteExpectation.fulfill()
},
failure: { error in
XCTFail("deleteFoo failed")
deleteExpectation.fulfill()
})
}
expectation.fulfill()
},
failure: { e in
expectation.fulfill()
})
waitForExpectationsWithTimeout(300.0) { (error) in
if error != nil {
XCTFail(error.localizedDescription)
}
}
}
感觉上我也需要混合使用nsrunlop/runMode
,但在安装和拆卸之外,这会锁定我。我确实在某一点上通过了底层的Alamofire代码,我想在这种情况下它会遇到阻塞问题(但这只是一个单元测试,所以这不是一个有意义的问题)
谢谢 不管它值多少钱,我最终在这里找到了一个很好的参考: 要点是,您可以使用GCD
dispatch\u group\t
创建一个基本测试类,如下所示:
class XCTestAsyncTest: XCTestCase {
static var dispatchGroup:dispatch_group_t = dispatch_group_create()
static func waitForGroup()
{
var didComplete = false;
dispatch_group_notify(self.dispatchGroup, dispatch_get_main_queue(), {
didComplete = true
})
while !didComplete {
NSRunLoop.currentRunLoop().runMode(NSDefaultRunLoopMode,
beforeDate: (NSDate.distantFuture() as? NSDate)!)
}
}
}
static func initializeData() {
var nora = Student()
nora.first = "Nora"
nora.last = "Norris"
nora.gender = .Female
createStudentAsync(&nora)
var mary = Student()
mary.first = "Mary"
mary.last = "Morison"
mary.gender = .Female
createStudentAsync(&mary)
waitForGroup()
// populate Mary
var mm1 = createCourseAsync(mary, text: "Mary's first class")
addCourse(&mm1)
var mm2 = createCourse(mary, text: "Mary's second class")
addCourse(&mm1)
var mm3 = createCourse(mary, text: "Mary's third class")
addCourse(&mm1)
waitForGroup()
...
因此,您可以编写类似以下(人为)示例的帮助器测试函数:
这样称呼它:
class XCTestAsyncTest: XCTestCase {
static var dispatchGroup:dispatch_group_t = dispatch_group_create()
static func waitForGroup()
{
var didComplete = false;
dispatch_group_notify(self.dispatchGroup, dispatch_get_main_queue(), {
didComplete = true
})
while !didComplete {
NSRunLoop.currentRunLoop().runMode(NSDefaultRunLoopMode,
beforeDate: (NSDate.distantFuture() as? NSDate)!)
}
}
}
static func initializeData() {
var nora = Student()
nora.first = "Nora"
nora.last = "Norris"
nora.gender = .Female
createStudentAsync(&nora)
var mary = Student()
mary.first = "Mary"
mary.last = "Morison"
mary.gender = .Female
createStudentAsync(&mary)
waitForGroup()
// populate Mary
var mm1 = createCourseAsync(mary, text: "Mary's first class")
addCourse(&mm1)
var mm2 = createCourse(mary, text: "Mary's second class")
addCourse(&mm1)
var mm3 = createCourse(mary, text: "Mary's third class")
addCourse(&mm1)
waitForGroup()
...
这在我的测试中是简单而有效的