我有一个实现自定义UIControl的库,该库的方法是在调用时触发一个.valueChanged事件。我想测试一下这种行为的方法。
我的自定义控件:
class MyControl: UIControl {
func fire() {
sendActions(for: .valueChanged)
}
}而测试:
import XCTest
class ControlEventObserver: NSObject {
var expectation: XCTestExpectation!
init(expectation anExpectation: XCTestExpectation) {
expectation = anExpectation
}
func observe() {
expectation.fulfill()
}
}
class Tests: XCTestCase {
func test() {
let myExpectation = expectation(description: "event fired")
let observer = ControlEventObserver(expectation: myExpectation)
let control = MyControl()
control.addTarget(observer, action: #selector(ControlEventObserver.observe), for: .valueChanged)
control.fire()
waitForExpectations(timeout: 1) { error in
XCTAssertNil(error)
}
}
}问题是observe方法永远不会被调用,因此expectation没有实现。
问题是:在这种情况下,我们如何测试UIControlEvents?也许我们需要以某种方式强迫运行环?
编辑1:请注意,由于我正在测试一个库,我的测试目标没有任何主机应用程序。当测试目标有主机应用程序时,上面的测试就通过了。
发布于 2016-10-04 16:00:14
当发生特定于控件的事件时,该控件立即调用任何相关的操作方法。操作方法通过当前的UIApplication对象进行分派,该对象在需要时按照响应链查找处理消息的适当对象。
当在一个sendActions(for:)上调用UIControl时,该控件将调用UIApplication的sendAction(_:to:from:for:)将事件传递给已注册的目标。
因为我正在测试一个没有主机应用程序的库,所以没有UIApplication对象。因此,.valueChanged事件不会被分派,observe方法也不会被调用。
发布于 2016-10-04 11:41:24
在测试方法中声明观察者对象。这意味着,一旦方法完成,它将从内存中释放,因此不会被调用。在Tests类中的类级别上创建一个对观察者的引用,如下所示,它将工作。
class Tests: XCTestCase {
var observer: ControlEventObserver!
func test() {
let myExpectation = expectation(description: "event fired")
self.observer = ControlEventObserver(expectation: myExpectation)
let control = MyControl()
control.addTarget(observer, action:#selector(ControlEventObserver.observe), for: .valueChanged)
control.fire()
waitForExpectations(timeout: 1) { error in
XCTAssertNil(error)
}
}
}您还需要以同样的方式声明myExpectation & control,否则也不会被调用。
https://stackoverflow.com/questions/39851205
复制相似问题