Xctest: может ли ожиданиеforpredicate выполняться при изменении асинхронной переменной?

Я использую ожидание (for: AssessmentWith: handler :), чтобы следить за изменением переменной в производственном коде, но оно никогда не выполняется - почему?

Я бы предпочел не загромождать свой производственный код, добавляя блоки искусственного завершения или уведомления.

class ProductionClass {
    var areWeDone = false

    func doSomeStuff() {
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
            self.areWeDone = true
        }
    }
}

class Test: XCTestCase {
    override func setUp() { }
    override func tearDown() { }

    func testDoSomeStuff() {
        let productionClass = ProductionClass()
        let predicate = NSPredicate(format: "areWeDone = %d", true)
        let exp = expectation(for: predicate, evaluatedWith: productionClass, handler: nil)

        productionClass.doSomeStuff()

        let result = XCTWaiter.wait(for: [exp], timeout: 3)
        if result != XCTWaiter.Result.completed {
            XCTAssert(false, "areWeDone changed but test timeout")
        }
   }
}
3
0
411
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Решение довольно простое - просто убедитесь, что класс «ProductionClass» наследуется от NSObject, и ваш тест будет работать должным образом:

import Foundation

class ProductionClass : NSObject {
    var areWeDone = false

    func doSomeStuff() {
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
            self.areWeDone = true
        }
    }
}

Я быстро исследовал свои тесты и заметил две вещи: 1. Как правильно говорит Дж. Д. Вудер, вы должны унаследовать свой производственный класс от NSObject (это то, что дает вам возможность вызывать методы времени выполнения obj-c и использовать методы KeyValue). 2. Тест больше не вылетает, но все равно не проходит. Чтобы исправить эту отметку, ваша переменная areWeDone со спецификатором @objc (чтобы она выглядела как @objc var areWeDone). В моем случае это работает.

В моем случае он работал без аннотации «@objc». Xcode 10.2.1, Swift 5

Jochen Holzer 18.07.2019 17:54

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