【问题标题】:Write xctest for function inside an operation queue为操作队列中的函数编写 xctest
【发布时间】:2021-10-02 01:22:47
【问题描述】:

我有一个如下函数,它向操作队列添加操作,我如何测试添加到操作队列的代码块,我尝试通过传递分析观察者间谍来使用期望并检查是否值已设置,但似乎不起作用,请指出正确的方向

func firePendingEvent() {
   for analyticItem in eventQueue {
     eventPriorityQueue.addOperationToQueue (operation: BlockOperation {
          self.analyticsObserver?.logEvent(event: analyticItem) // write test to check the event inside this function
      }, priority: .normal)
      if eventQueue.count > 0 {
        eventQueue.remove(at: 0)
      }
    }    
}  

【问题讨论】:

  • eventQueue 是什么类型?一个集合的并发迭代和修改通常是非法的

标签: swift asynchronous xctest operationqueue


【解决方案1】:

基本思想是您的测试必须创建一个期望:

let e = expectation(description: "testGetUsers")

然后当你的异步方法完成后,实现这个期望:

e.fulfill()

然后,当然,您的测试必须在启动异步任务后,等待期望:

waitForExpectations(timeout: 10)

但是,显然,您需要知道您的功能何时完成。我建议给它一个可选的完成处理程序:

func firePendingEvent(completion: (() -> Void)? = nil) {
    let group = DispatchGroup()

    for analyticItem in eventQueue {
        group.enter()
        eventPriorityQueue.addOperationToQueue(operation: BlockOperation {
            self.analyticsObserver?.logEvent(event: analyticItem)
            group.leave()
        }, priority: .normal)
    }
    eventQueue.removeAll()

    if let completion = completion {
        group.notify(queue: .main, execute: completion)
    }
}

(请注意,我个人避免在迭代数组时对其进行变异,因此我将所有任务添加到队列中并推迟 removeAll 直到我不再迭代。)

无论如何,您现在可以编写测试了:

func testFirePendingEvents() {
    let e = expectation(description: "testGetUsers")

    foo.firePendingEvent {
        XCAssert(…) // do whatever tests are appropriate
        e.fulfill()
    }

    waitForExpectations(timeout: 10)
}

但是,由于该完成处理程序是可选的,并且默认为 nil,因此您不必更改未利用新完成处理程序的其余代码。

就我个人而言,我会向该完成处理程序闭包添加一个参数以传回您想要测试的任何值,但问题中不足以知道您正在测试什么结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多