如何测试依赖于 UIUserInterfaceIdiom (ios) 的代码

lin*_*fox 5 xcode unit-testing octest ios

我有一些 Objective-C [i-os] 代码,我想使用 XCode 运行单元测试。它根据设备类型访问不同的元数据,使用:

[[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad

我遇到的问题是,当我运行单元测试时,这个结果总是正确的。理想情况下,如果能够在测试运行时对其进行设置,那就太好了。

我猜想可以做到的方法是创建一个类来封装设备检查并模拟测试。但我认为是否有更好的解决方案可能值得一看。

作为参考,有一篇不错的博客文章,其中包含许多链接、Apple单元测试指南和单元测试示例代码项目。

Vic*_*ima 6

今天早上我尝试了几种不同的方法:

  1. 使用UIDevice仅链接到我的测试目标的类别。在该类别中,我将currentDevice使用partialMock实现 ( OCMock) 覆盖并存根必要的方法,以便它强制将 Pad 或 Phone 返回到我的具体测试。它应该可以工作,但是很难弄乱诸如UIDevice或 之类的类UIApplication,模拟器经常崩溃,这是一个坏兆头。

  2. #undef UI_INTERFACE_IDIOM()并#define在我的测试中.pch。将UI_INTERFACE_IDIOM()测试中的实现指向我自己的单例实例,我可以相应地将其设置为 Pad 或 Phone。这可行,但主要问题是,当您运行测试时,模拟器也会启动(即应用程序测试),因此如果您在 iPad 上运行测试,您的测试将通过,但模拟器的其他部分将失败,因为它得到的矛盾响应UI_INTERFACE_IDIOM()(其中之一是如果您处于通用应用程序环境中,则加载特定于 iPhone 的笔尖)

  3. 我认为这是最好的方法。与计算机科学中的所有内容一样,只需在 =) 中放置另一层即可,而不是使用代码来UI_INTERFACE_IDIOM()评估它是否在 Pad 或 Phone 设备上,而是将此逻辑封装在一个可以在测试期间模拟的对象中。这种方式UI_INTERFACE_IDIOM()仍然适用于模拟器的其余部分。您的生产代码实际上将依赖于它,但您的测试将依赖于可以在测试中按预期响应的存根实现。

如果您愿意,我可以分享一些有关此问题的代码。是的,这真是令人厌倦!

您是如何解决这个问题的?