如何测试是否已触发UIControlEvents

Tha*_*ham 2 selector nsrunloop ios xctest swift

我有一个实现自定义的库UIControl,其方法是.valueChanged在调用时触发事件.我想测试该行为的方法.

我的自定义控件:

class MyControl: UIControl {
    func fire() {
        sendActions(for: .valueChanged)
    }
}
Run Code Online (Sandbox Code Playgroud)

而且测试:

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)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是observe方法永远不会被调用,所以expectation不满足.

问题是:UIControlEvents在这种情况下我们如何测试?也许我们需要以某种方式强制运行runloop?

编辑1:请注意,因为我正在测试库,我的测试目标没有任何主机应用程序.当测试目标具有主机应用程序时,上述测试通过.

Tha*_*ham 10

Apple的UIControl文档指出:

当发生控件特定事件时,控件立即调用任何关联的操作方法.通过当前UIApplication对象调度操作方法,该对象根据需要在响应者链之后找到处理消息的适当对象.

sendActions(for:)在UIControl上调用时,控件将调用UIApplication's' sendAction(_:to:from:for:)将事件传递给已注册的目标.

由于我在没有任何Host Application的情况下测试库,因此没有UIApplication对象.因此,.valueChanged不调度该事件,并且不调用该observe方法.