I have a library implementing a custom UIControl
with a method which would fire a .valueChanged
event when called. I would like to test the method
Apple's documentation for UIControl states that:
When a control-specific event occurs, the control calls any associated action methods right away. Action methods are dispatched through the current UIApplication object, which finds an appropriate object to handle the message, following the responder chain if needed.
When sendActions(for:)
is called on a UIControl, the control will call the UIApplication
's sendAction(_:to:from:for:)
to deliver the event to the registered target.
Since I am testing a library without any Host Application, there is no UIApplication
object. Hence, the .valueChanged
event is not dispatched and the observe
method does not get called.
You are declaring the observer object inside the test method. This means that as soon as the method completes it will be released from memory and hence is not called. Create a reference to the observer at class level in the Tests
class as follows and it will work.
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)
}
}
}
You will also need the myExpectation
& control
to be declared in the same way else that won't be called either.