如何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:) ,控件将调用UIApplicationsendAction(_: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) } } } 

您还需要以与其他方式不同的方式声明myExpectationcontrol