如何TDD UIGestureRecognizers?
在尝试使用 UIGestureRecognizer 编写 TDD 代码时,我发现无法以编程方式验证目标操作。如果没有这个,我不确定我是否可以正确测试它。
如果手势识别器在 IB 中设置(支持 iOS 5+),则目标动作会在 NIB/Storyboard 加载时设置;如果在代码中完成,它会使用 initWithTarget:action:,这两者都意味着没有多少模拟能够检测到目标操作。
我没主意了。如果有人成功测试了 UIGestureRecognizer,我可以使用建议。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不幸的是,您正在尝试检查一个框架类,该框架类在编写时并未考虑到测试,因此不会公开您想要验证的状态。这将使断言您想要检查的目标操作对是否存在变得困难。在这种情况下,我有您可以使用的三个选项,但没有一个是很好的解决方案:
您可以子类化 UIGestureRecognizer,重写目标操作方法以将注册对保存在集合中,然后可以将其公开给该类的用户,然后调用这些方法的超类实现。不幸的是,您引入新类只是为了使测试更容易,必须记住使用它们,并且可能必须从 UIGestureRecognizer 转换为自定义子类,具体取决于您从何处获取手势识别器引用。
或者,您的测试可以将新版本的目标操作方法混合到 UIGestureRecognizer 中,为您提供跟踪添加目标的钩子。只需确保在完成后将原始方法实现交换回原位,否则将来的测试将出现意外行为。
最后,您也许能够找到一个私有 API 调用,它为您提供了一种检查手势识别器上注册的目标操作的方法。只需确保私有 API 调用仅保留在您的测试代码中即可。
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.
这就是我在 Swift 中对点击手势识别器进行单元测试的方法。该测试确保响应点击手势的代码被执行。
首先,我创建一个 OnTap 帮助器类
接下来,我注册一个带有视图和回调闭包的点击手势
最后,我在单元测试中模拟点击并检查闭包是否已被调用
注意,这是一种单元测试技术。此外,我使用 UI 测试来确保所有部分都能和谐地协同工作。
This is how I unit test tap gesture recognizer in Swift. The test makes sure the code that responds to the tap gesture is executed.
First, I create an OnTap helper class
Next, I register a tap gesture wit a view and a callback closure
Finally, I simulate the tap in my unit test and check that the closure has been called
Note, this is a unit testing technique. In addition, I use UI tests to make sure all pieces work together in sweet harmony.
我建议对手势识别器进行子类化,如下所示:
I'd suggest to subclass the gesture recognizer as follows:
如果有人对使用私有 API 的解决方案感兴趣,UIGestureRecognizer 上的以下类别可用于发送手势识别操作。正如 Jonah 指出的那样,不要在生产代码中使用它。
If anyone is interested in a solution that uses private API, The following category on UIGestureRecognizer can be used to send gesture recognition actions. As Jonah points out, do not use it in production code.