使用UIWindow()进行单元测试时的NSInternalConsistencyException

时间:2016-07-13 23:43:52

标签: ios swift unit-testing uialertcontroller uiwindow

我一直在使用following post作为指导,了解如何从与特定APIContext defaultContext = new APIContext(clientId1, clientSecret1, "sandbox"); APIContext sandboxContext = new APIContext(clientId2, clientSecret2, "sandbox"); APIContext someOtherContext = new APIContext(clientId3, clientSecret3, "live"); APIContext liveContext = new APIContext(clientId, clientSecret, "live"); // Now pass any of the above context in these calls, and it would use those configurations. Payment payment = new Payment(); // Fill in all the details. payment.create(defaultContext); // Replace that defaultContext with any of those other contexts. 无关的代码中显示UIAlertController。现在,我想对这段代码进行单元测试:

UIViewController

但是,在func showAlert(alert: UIAlertController, animated: Bool, completion: (()->Void)?) { let alertWindow = UIWindow(frame: UIScreen.mainScreen().bounds) // Keep a strong refence to the window. // We manually set this to nil when the alert is dismissed self.alertWindow = alertWindow alertWindow.rootViewController = UIViewController() if let currentTopWindow = UIApplication.sharedApplication().windows.last { alertWindow.windowLevel = currentTopWindow.windowLevel + 1 } else { // This case only happens during unit testing Logger.trace(ICELogLevel.Error, category: .Utility, message: "The application doesn't have a window being displayed!") } // preload the viewController for unit testing // (see https://www.natashatherobot.com/ios-testing-view-controllers-swift/ ) let _ = alertWindow.rootViewController?.view alertWindow.makeKeyAndVisible() alertWindow.rootViewController!.presentViewController(self.alertController, animated: animated, completion: completion) } 行上运行单元测试时,我得到alertWindow.makeKeyAndVisible()

此代码适用于应用代码,我不想使用模拟UIWindow等,因为我希望验证警告实际显示在真实 UIWindow。

有关如何在单元测试中使用UIWindows()的任何指导?我做错了什么?

2 个答案:

答案 0 :(得分:5)

问题是makeKeyAndVisible调用内部需要运行的UIApplication实例的代码。这就是在测试框架时抛出异常而在测试应用程序时抛出异常的原因。应用程序测试将测试包注入正在运行的应用程序简单的解决方法是从:

alertWindow.makeKeyAndVisible()

alertWindow.isHidden = false

这样可以使视图控制器与窗口隔离进行测试。缺点当然是这与makeKeyAndVisible不是相同 - 它没有触发异常的副作用。

另一个策略是专门创建一个新的空应用程序目标以支持测试。在其中嵌入测试框架并将其用作单元测试的宿主应用程序。

答案 1 :(得分:0)

我们还没有解决UIWindow是否可以设置为在单元测试环境中工作的问题,但是@ matt的评论让我思考,这可能不是我们需要做的事情首先进行单元测试,原因如下:

  1. 我们已经有通过警报方案运行的UI测试。如果构建中断了显示的警报,我们会很快注意到
  2. 对于其余的单元测试目的,我们可以简单地将此方法存根,以立即调用完成回调。
  3. 根据问题的原始动机,似乎没有一种方法可以在单元测试中正确使用UIWindow对象。