在 XCTestCase 的 setUp() 中等待多个异步调用
Wait for multiple async calls in setUp() of XCTestCase
我需要执行多次调用才能让 test()
方法 运行。我有一个完成块,我正在使用 waitForExpectations()
。由于有多个异步调用,我使用了一个计数器。我让 expectation.fulfill()
仅在计数器达到调用次数时发生。
override func setUp() {
super.setUp()
let exp = expectation(description: "waitForSetUp")
var counter = 0
// Issue an async request
self.addEventToCalendar(title: "Test1", description: "Description test1", startDate: NSDate().addingTimeInterval(-36000), endDate: NSDate()){(success, error) in
if (success) && (error == nil) {
counter = counter + 1
if(counter == 2){exp.fulfill()}
}
}
self.addEventToCalendar(title: "Test2", description: "Description test2", startDate: NSDate(), endDate: NSDate().addingTimeInterval(36000)){(success, error) in
if (success) && (error == nil) {
counter = counter + 1
if(counter == 2){exp.fulfill()}
}
}
waitForExpectations(timeout: 40, handler: nil)
}
这个构造不起作用。在调用返回之前 test()
方法有时是 运行(并非总是如此)。
如何让 setUp()
等待返回多个异步调用?
我有一个类似的案例。我最终做的解决方案是调用几个函数,这些函数增加了对我的先决条件的期望,并将期望的超时设置为合理的值。在期望的完成处理程序中,我触发了设置算法的下一步。在所有初步步骤通过后,我开始实际的测试逻辑。
正在将 link 附加到 Apple 文档。
编辑:请参阅下面的示例代码:
class CommonTests: XCTestCase {
var validate: XCTestExpectation? = nil
func testMytest() {
validate(completion: {
loadSomeStuff(completion: { (list: [Stuff]?) in
// actual test
}
})
}
func validate(completion: @escaping ()->()) {
self.validateExpectation = self.expectation(description: "Setup")
// async operation can be fired here
// or if already started from somewhere else just wait for it to complete
self.waitForExpectations(timeout: 60) { (error: Error?) in
XCTAssert((error == nil), error?.localizedDescription ?? "Failed with unknown error")
completion()
}
}
func validateAsyncCompleted() {
self.validateExpectation?.fulfill()
}
func loadStuff(completion: @escaping ([Stuff]?)->()) {
// possible place for assertion or some other checks
let expectation = self.expectation(description: "loading")
DispatchQueue.global().async {
let result: [Stuff]? = nil
// load operation
expectation.fulfill()
completion(result)
}
self.waitForExpectations(timeout: 90) { (error: Error?) in
XCTAssert((error == nil), error?.localizedDescription ?? "load - failed with unknown error")
}
}
}
注意:期望有两种方法,第一种期望保存在变量中,因此如果需要可以从另一个函数中实现,另一种是在函数体中本地创建并从闭包中实现。
我需要执行多次调用才能让 test()
方法 运行。我有一个完成块,我正在使用 waitForExpectations()
。由于有多个异步调用,我使用了一个计数器。我让 expectation.fulfill()
仅在计数器达到调用次数时发生。
override func setUp() {
super.setUp()
let exp = expectation(description: "waitForSetUp")
var counter = 0
// Issue an async request
self.addEventToCalendar(title: "Test1", description: "Description test1", startDate: NSDate().addingTimeInterval(-36000), endDate: NSDate()){(success, error) in
if (success) && (error == nil) {
counter = counter + 1
if(counter == 2){exp.fulfill()}
}
}
self.addEventToCalendar(title: "Test2", description: "Description test2", startDate: NSDate(), endDate: NSDate().addingTimeInterval(36000)){(success, error) in
if (success) && (error == nil) {
counter = counter + 1
if(counter == 2){exp.fulfill()}
}
}
waitForExpectations(timeout: 40, handler: nil)
}
这个构造不起作用。在调用返回之前 test()
方法有时是 运行(并非总是如此)。
如何让 setUp()
等待返回多个异步调用?
我有一个类似的案例。我最终做的解决方案是调用几个函数,这些函数增加了对我的先决条件的期望,并将期望的超时设置为合理的值。在期望的完成处理程序中,我触发了设置算法的下一步。在所有初步步骤通过后,我开始实际的测试逻辑。
正在将 link 附加到 Apple 文档。
编辑:请参阅下面的示例代码:
class CommonTests: XCTestCase {
var validate: XCTestExpectation? = nil
func testMytest() {
validate(completion: {
loadSomeStuff(completion: { (list: [Stuff]?) in
// actual test
}
})
}
func validate(completion: @escaping ()->()) {
self.validateExpectation = self.expectation(description: "Setup")
// async operation can be fired here
// or if already started from somewhere else just wait for it to complete
self.waitForExpectations(timeout: 60) { (error: Error?) in
XCTAssert((error == nil), error?.localizedDescription ?? "Failed with unknown error")
completion()
}
}
func validateAsyncCompleted() {
self.validateExpectation?.fulfill()
}
func loadStuff(completion: @escaping ([Stuff]?)->()) {
// possible place for assertion or some other checks
let expectation = self.expectation(description: "loading")
DispatchQueue.global().async {
let result: [Stuff]? = nil
// load operation
expectation.fulfill()
completion(result)
}
self.waitForExpectations(timeout: 90) { (error: Error?) in
XCTAssert((error == nil), error?.localizedDescription ?? "load - failed with unknown error")
}
}
}
注意:期望有两种方法,第一种期望保存在变量中,因此如果需要可以从另一个函数中实现,另一种是在函数体中本地创建并从闭包中实现。