【发布时间】:2021-01-25 10:04:00
【问题描述】:
我正在尝试编写单元测试,我希望我的测试用例等待某个类中的变量发生变化。所以我用谓词创建了一个期望,并等待使用XCTWaiter().wait(for: [expectation], timeout: 2.0) 改变值,我认为这是正确的使用方法。
以下代码按预期工作:
class ExpectationTests: XCTestCase {
var x: Int = 0
private func start() {
_ = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false) { _ in
self.x = 1
}
}
func test1() {
let predicate = NSPredicate(format: "x == 1")
let expectation = XCTNSPredicateExpectation(predicate: predicate, object: self)
start()
let result = XCTWaiter().wait(for: [expectation], timeout: 2.0)
switch result {
case .completed: XCTAssertEqual(x, 1)
case .timedOut: XCTFail()
default: XCTFail()
}
}
变量 (x) 被 start() 函数设置为 0,然后在 0.5s 后变为 1。谓词等待该 var (x) 更改。这有效:result 设置为 .completed,而 var 实际上设置为 1。是的 :-)
但是,当我要观察的变量不是本地变量,而是在某个类中时,它不再起作用。考虑以下代码片段:
class MyClass: NSObject {
var y: Int = 0
func start() {
_ = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false) { _ in
self.y = 1
}
}
}
func test2() {
let myClass = MyClass()
let predicate = NSPredicate(format: "y == 1")
let expectation = XCTNSPredicateExpectation(predicate: predicate, object: myClass)
myClass.start()
let result = XCTWaiter().wait(for: [expectation], timeout: 2.0)
switch result {
case .completed: XCTAssertEqual(myClass.y, 1)
case .timedOut: XCTFail()
default: XCTFail()
}
}
它与第一段代码非常相似,但它总是在 2 秒后结束,result 是 .timedOut。我看不出我做错了什么。我使用来自对象myClass 的变量,而不是本地变量和对象'self',我将其传递给期望值。 (类 var myClass.y 实际上在测试结束时设置为 1。)
我尝试将XCTNSPredicateExpectation(predicate:object) 替换为expectation(for:evaluatedWith:handler),但这并没有什么不同。
StackOverflow 上的许多示例都使用谓词检查 XCUIElement 中的 exists。但我不是在测试 UI;我只想检查某个类中的某个 var 是否在超时时间内发生了变化。我不明白为什么这与在 XCUIElement 中检查 var exists 如此不同。
有什么想法吗?!提前谢谢!
【问题讨论】:
-
试试
@objc var y: Int = 0。 -
谢谢@Willeke,这行得通!好吧,至少一堂课。 (我也需要它作为结构,我不能在那里使用'@objc'。)更重要的是,我无法访问具有我想要观察的属性的类,所以我不能只添加'@objc ' 到一个 var 那里。 (我提供的例子只是为了演示问题;实际上,它有点复杂。)无论如何,我仍然不明白问题是什么。在我在 Stack Overflow 上找到的所有示例中,人们都在使用 XCUIElement 类的属性“存在”以及我正在使用的相同代码。那么为什么我的代码不起作用?!
-
NSPredicate(format: "y == 1")使用 KVC,value(forKey: "y")。 -
嗨@Willeke,谢谢你的建议,但你能详细说明一下吗?我总是收到“对象不符合“y”属性的 KVC 错误消息。您如何建议我更改谓词以使其起作用?
-
我不熟悉
XCTest框架。我的猜测是NSPredicate(block:)和/或设置expectation.handler。
标签: swift nspredicate xctest expectations xctestexpectation