如何解决带有XCTestExpectation和NSPredicate的XCTWaiterwait似乎失败
我正在尝试编写单元测试,以使我的测试用例等待某个类中的变量发生更改。因此,我用谓词创建了一个期望值,并等待使用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)设置为0,然后通过start()函数在0.5秒后变为1。谓词等待该变量(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上的许多示例都使用谓词来检查exists
中的XCUIElement
。但是我不是在测试UI。我只想检查某个类中的某些var是否在超时时间内更改了。我不明白为什么这与在exists
中检查var XCUIElement
有何不同。
有什么想法吗?!预先谢谢你!
解决方法
好吧,感谢@Willeke向我指出了正确的方向,我确实找到了解决方案,但是我不能说我完全理解它... 这是我的代码现在的样子:
// MARK: - Test 2
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() { any,_ in
// guard let myClass = any as? MyClass else { return false }
return myClass.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()
}
}
我可以使用带闭包的谓词,该谓词可以定期检查var是否已更改,如果它具有正确的值,则返回true。 (大约每秒执行一次。)但是,实际上,考虑到XCTWaiter
文档中的描述(这是expectation(for:evaluatedWith:handler:)
的便捷方法),我实际上就是XCTNSPredicateExpectation
的目的。 :
期望定期评估谓词。谓词评估为true时,该测试即可满足期望。
所以,我很高兴继续前进,但是我仍然不明白为什么这不适用于NSPredicate(format: "y == 1")
而不是带有闭包的谓词...
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。