Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 使用UIWindow()进行单元测试时的内部一致性异常_Ios_Swift_Unit Testing_Uialertcontroller_Uiwindow - Fatal编程技术网

Ios 使用UIWindow()进行单元测试时的内部一致性异常

Ios 使用UIWindow()进行单元测试时的内部一致性异常,ios,swift,unit-testing,uialertcontroller,uiwindow,Ios,Swift,Unit Testing,Uialertcontroller,Uiwindow,我一直在使用作为如何从与特定UIViewController无关的代码中显示UIAlertController的指南。现在,我想对这段代码进行单元测试: func showAlert(alert: UIAlertController, animated: Bool, completion: (()->Void)?) { let alertWindow = UIWindow(frame: UIScreen.mainScreen().bounds) // Keep a st

我一直在使用作为如何从与特定
UIViewController
无关的代码中显示
UIAlertController
的指南。现在,我想对这段代码进行单元测试:

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()
行上,我得到一个
nSinternalinconsistenceException:props必须有一个有效的clientID

此代码在应用程序代码中起作用,我不希望使用模拟UIWindow等,因为我希望验证警报是否实际显示在realUIWindow上


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

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

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

  • 问题在于
    makeKeyAndVisible
    调用内部需要运行UIApplication实例的代码。这就是为什么在测试框架时抛出异常,而不是在测试应用程序时抛出异常。应用程序测试将测试包注入正在运行的应用程序。简单的解决方法是从以下位置移动:

    alertWindow.makeKeyAndVisible()

    alertWindow.ishiden=false

    这可以工作,并允许在与窗口隔离的情况下测试视图控制器。当然,缺点是这与
    makeKeyAndVisible
    不同-它没有触发异常的副作用


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

    这可能不是你想听的,但在我看来,你所做的总是错的。用这种方式在视图层次结构中添加一个额外的UIWindow是没有用的。-然而,更有用的是:这真的是您想要进行单元测试的东西吗?它听起来更像是UI测试的候选者。我不认为这是黑客行为。有关添加UIWindows的意义,请参见。我认为这是其中之一——我们希望此警报“浮动”在其他UI元素之上。此外,我问题中的链接帖子表明,这是苹果公司针对UIAlertController问题的内部解决方案。苹果公司自己的警报(比如,打电话进来)当然是windows。但这不在应用程序的范围之内。这并不意味着你应该这样做,也不是UIAlertController的工作方式。听着,如果你愿意,我可以给你一个完全正常的非黑客非窗口方式,让自定义警报“浮动”在其他UI元素之上。当然,你想走哪条路完全取决于你自己。是的,我一直在关注我问题开始时链接的帖子。如果有更好的方法可以做到这一点的话,我很清楚正确的现代方法是什么——浮动警报的位置、大小和内容完全取决于你。碰巧,我曾试图使其看起来像UIAlertController的视图,但您不需要通过任何方式这样做。我有一个框架,用于测试这些UIKIt相关的副作用是否发生,我目前正在尝试将该框架嵌入虚拟应用程序中。您以前是否尝试过这样做,并且可以提供任何指导?