【问题标题】:Testing pushViewController in Swift在 Swift 中测试 pushViewController
【发布时间】:2016-11-20 11:05:10
【问题描述】:

我尝试设置一个路由器来导航到正确的 Viewcontroller。当我在模拟器中调用它时,它确实工作正常。

但是:当我尝试通过我的 NavigationController 的 topViewController 或 presentViewController 属性测试此转换的结果时,我总是得到每个 Viewcontroller,但不是正确的。

我的方法如下所示:

func navigateToViewController(_ viewController: UIViewController, animated: Bool) {
    self.pushViewController(viewController, animated: animated)
}

正如我所说。它在模拟器中运行良好,但我想对其进行测试。每次我调用它时,ViewController 都已正确设置。但是Test的结果是完全不同的Controller。

当我断言 topViewController 或 presentViewController 应该是 HomeViewController 时,我总是得到不同的 ViewController 作为结果。

XCTAssertTrue(self.sut.topViewController is HomeViewController,
                   "The TopViewController should be set to the HomeViewController but instead: \(self.sut.topViewController)")

这怎么可能,我该如何解决?

【问题讨论】:

  • 你想要单元测试还是 UI 测试?
  • 这应该是我路由器的单元测试。这样一切都是正确的,包括呈现的 ViewController。
  • 看起来你的类是 NavigationController 的子类或扩展。你能多分享一点它的界面吗?
  • 不。控制器的实例是相同的。这就是为什么我不明白为什么它不起作用。在 NavigationViewController 中无非是一个基于 String 的 switch 来准备 ViewController,它将被传递给 "navigateToViewController" 方法。
  • 这里我有一个示例项目,其中仅包含出现问题的部分。希望有人可以帮助我解决这个问题。 github.com/Evil-Me/SegueUnitTestApp

标签: ios swift unit-testing uinavigationcontroller xctest


【解决方案1】:

更新答案:

使用https://github.com/jonreid/ViewControllerPresentationSpy

原答案:

似乎没有一个好的方法来单元测试调用performSegue效果。我们可以做的是记录它是如何被调用的。在测试代​​码中,添加:

fileprivate var performSegueIdentifiers: [String] = []

extension ViewController {
    override open func performSegue(withIdentifier identifier: String, sender: Any?) {
        performSegueIdentifiers.append(identifier)
     }
}

这会改变 ViewController 的 performSegue。我们没有实际执行segue,而是将标识符附加到performSegueIdentifiers。由于这是文件范围,我们需要小心不要让它“渗入”其他测试。所以在setUp重置它:

    override func setUp() {
        super.setUp()
        performSegueIdentifiers = []
        // other set-up
    }

现在您的测试可以调用 test 这个数组的内容来确定:

  • performSegue 被调用的次数
  • 传递给它的 segue 标识符

我们可以相信实际的performSegue 有效。我们只需要测试生产代码是否正确调用它。

【讨论】:

  • 感谢乔恩的回复。我明天早上直接试试这个。到目前为止听起来不错。非常感谢您的帮助。我很感激。
  • 乔恩,你是我的英雄。它就像一个魅力。我现在可以看到执行了什么 segue 并且可以检查它。非常感谢。
【解决方案2】:

试试这段代码,它将帮助您获取导航控制器的视图控制器堆栈中每个视图控制器的类名

for VC in (self.navigationController?.viewControllers)! {
            print(VC.classForCoder)
        }

因为我不确定您的代码中还有什么可能将一些视图控制器添加到导航控制器的视图控制器堆栈中

【讨论】:

  • 我做了这个,控制器没有出现在那里。
猜你喜欢
  • 1970-01-01
  • 2016-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-21
相关资源
最近更新 更多