我一直在使用following post作为如何从与特定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()行上,我得到了NSInternalInconsistencyException: props must have a valid clientID

该代码在应用程序代码中有效,并且我不希望使用模拟UIWindow等,因为我希望确认警报实际上是在实际 UIWindow上显示的实际上是

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

最佳答案

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

alertWindow.isHidden = false
这可以正常工作,并允许视图控制器与窗口隔离进行测试。缺点当然是这与makeKeyAndVisible不同-它没有触发异常的副作用。

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

10-06 08:52
查看更多