2017-02-16 23 views
1

我需要在运行test()方法之前执行多个调用。我有一个完成块,我正在使用waitForExpectations()。由于我使用了一个计数器,因此有多个异步调用。只有当计数器达到呼叫次数时,我才让expectation.fulfill()发生。在XCTestCase的setUp()中等待多个异步调用

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()等待返回多个异步调用?

+0

您是否尝试过实施处理程序并检查可能的错误? – user3581248

回答

1

我有一个类似的情况。我最终做的解决方案是调用几个函数,这些函数增加了对我的先决条件的期望,并将期望的超时设置为合理的值。在期望的完成处理程序中,我触发了我的设置算法的下一步。在所有初步步骤通过后,我开始实际的测试逻辑。

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

注:有2种方式的期望,第一个期望被保存在一个变量,因此它可以从另一个函数如果需要满足,另一个是在函数体中本地创建的,并从闭包中完成。