我正在尝试在我的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之后,单元测试证明是一件令人头痛的问题
答案 0 :(得分:6)
您无法将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教程以了解具体方法。