无法在XCTestCase对象(或引用它的任何对象)中访问AppDelegate

时间:2015-08-13 14:14:27

标签: ios xcode swift xctest

我正在尝试在我的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之后,单元测试证明是一件令人头痛的问题

1 个答案:

答案 0 :(得分:6)

您无法将AppDelegate.swift添加到测试目标中。 这导致在测试目标命名空间也创建类,它将是重复的。

AppDelegate对象在测试目标上展开时如果失败,因为该对象属于主目标上定义的类AppDelegate的版本,但是代码正在尝试解包该对象好像它属于测试目标上定义的版本。

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

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

然后导入模块并访问对象,如下所示:

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教程以了解具体方法。