【问题标题】:Cannot access AppDelegate in XCTestCase objects (or anything that references it)无法访问 XCTestCase 对象(或任何引用它的对象)中的 AppDelegate
【发布时间】:2015-08-13 14:14:27
【问题描述】:

我正在尝试在我的 swift iOS 应用程序上开始单元测试,但遇到了完全的障碍。我似乎无法访问使用我的 appDelegate 的任何内容。

我的 appDelegate 有一个 UserController 对象,它存储和管理登录的用户及其各种数据。为了简化调用userController,我创建了一个NSObject 的自定义子类,我的所有模型类都是它的子类。里面有

let userController : UserController = (UIApplication.sharedApplication().delegate as! AppDelegate).userController

每当我尝试测试其中一个子类化模型时,此行都会导致 SIGABRT 异常。

无法将“MyProject.AppDelegate”类型的值转换为 'MyProjectionTests.AppDelegate'。

我曾尝试从测试目标中删除 AppDelegate,但这让我的 AppDelegate 未定义。我曾尝试将import MyProject 添加到测试文件的顶部,但这也不起作用。

我见过另外两种解决方案:

  • 将应用程序委托功能设为私有 - 我真的很讨厌这样做 像这样的东西。如果我必须进行测试有什么意义 专门为测试更改我的代码。

  • 实现一个测试应用委托并使用它——这又是什么意思 在测试我是否不测试项目中的内容。

谁有解决办法。在 RSpec 使用 Rails 变得如此简单之后,事实证明 Swift 中的单元测试完全令人头疼

【问题讨论】:

    标签: ios xcode swift xctest


    【解决方案1】:

    您不能将AppDelegate.swift 添加到测试目标。 这会导致该类也在测试目标名称空间中创建,并且它将是重复的。

    AppDelegate 对象在测试目标上解包失败时,因为该对象属于在主目标上定义的类 AppDelegate 的版本,但代码是否试图解包对象,就好像它属于到测试目标上定义的版本。

    需要的是让主目标有一个模块,这样他的所有类都可以像任何工具包一样导入到测试代码中。

    要将主要目标定义为模块,请执行以下操作:

    然后像这样导入模块并访问对象:

    import UIKit
    import XCTest
    import MyApp
    
    
    class MyAppTests: XCTestCase {
    
        func testExample() {
          let userController : UserController = (UIApplication.sharedApplication().delegate as!  AppDelegate).userController
        //or explicitly referencing the module
    let userController : MyApp.UserController = (UIApplication.sharedApplication().delegate as!  AppDelegate).userController 
        }
    }
    

    }

    AppDelegate 和属性userController 必须公开。 如果您已经在使用 Swift 2.0,则可以使用 testable 属性而不是更改隔离级别。查看this 教程以了解如何操作。

    【讨论】:

    • 感谢您的建议。我最终所做的基本上是从应用程序委托中重构尽可能多的代码。从将它带入单元测试的尴尬程度来看,我认为我没有按预期使用它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-06
    • 1970-01-01
    • 2017-08-13
    • 2023-03-07
    • 2019-09-14
    相关资源
    最近更新 更多