如何testingUIControlEvents是否被触发
我有一个库实现自定义UIControl
与一个方法,将调用.valueChanged
事件时调用。 我想testing该行为的方法。
我的自定义控件:
class MyControl: UIControl { func fire() { sendActions(for: .valueChanged) } }
和testing:
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
没有实现。
问题是:如何在这种情况下testingUIControlEvents
? 也许我们需要强制runloop?
编辑1:请注意,由于我正在testing一个库,我的testing目标没有任何主机应用程序。 当testing目标有主机应用程序时,上述testing通过。
苹果公司的UIControl文件指出:
当发生特定于控件的事件时,控件立即调用任何相关的操作方法。 Action方法通过当前的UIApplication对象分派 ,如果需要的话,在响应者链之后find一个适当的对象来处理消息。
当在UIControl上调用sendActions(for:)
,控件将调用UIApplication
的sendAction(_:to:from:for:)
将事件传递给已注册的目标。
由于我正在testing没有任何主机应用程序的库,所以没有UIApplication
对象。 因此, .valueChanged
事件不会被调度, observe
方法也不会被调用。
您正在testing方法内部声明观察者对象。 这意味着只要方法完成,它将从内存中释放,因此不会被调用。 在Tests
类的class级别创build一个对观察者的引用,如下所示。
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
。