nheagy nheagy - 1 month ago 6
Objective-C Question

How to TDD UIGestureRecognizers?

While trying to TDD code that would otherwise use a UIGestureRecognizer, I found no way to programatically verify the target-action. Without this, I'm not certain I can properly test it.

If the gesture recognizer is setup in IB (with iOS 5+ support) the target-action is setup when the NIB/Storyboard loads; if done in code it uses initWithTarget:action:, both of which mean that no amount of mocking would be able to detect the target-action.

I'm out of ideas. If anyone has successfully test-driven a UIGestureRecognizer I could use the advice.

Answer

Unfortunately you're trying to inspect a framework class which wasn't written with testing in mind and so doesn't expose the state you want to verify. That is going to make it difficult to assert on the existence of the target-action pairs you want to check for. In such a case I have three options you might use, none of which are great solutions:

You might be able to subclass UIGestureRecognizer, override the target-action methods to save the registered pairs in a collection you can then expose to users of the class, and then call the superclass implementations of those methods. Unfortunately then you're introducing new classes just to make testing easier, have to remember to use them, and may have to cast from UIGestureRecognizer to your custom subclass depending on where you get a gesture recognizer reference from.

Alternately your test could swizzle new versions of the target-action methods into UIGestureRecognizer giving you a hook to track added targets. Just make sure to swap the original method implementations back into place when you're done or future tests will have unexpected behavior.

Finally you might be able to find a private API call which gives you a way to check the registered target-actions on the gesture recognizer. Just make sure that private API call remains only in your test code.