Напишите xctest для функции внутри очереди операций

У меня есть следующая функция, которая добавляет операцию в очередь операций, как мне протестировать блок кода, который добавляется в очередь операций, я попытался использовать ожидание, передав шпион наблюдателя аналитики и проверить, установлено ли значение но, похоже, это не работает, укажите мне правильное направление

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

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, вам не нужно изменять остальную часть вашего кода, который не использует новый обработчик завершения.

Лично я бы добавил параметр к этому закрытию обработчика завершения, чтобы передать обратно любое значение, которое вы хотите проверить, но в вопросе было недостаточно, чтобы знать, какой результат вы тестируете.

Другие вопросы по тегам