当 testes 函数调用 AppDelegate + managed Object 时单元测试崩溃

Posted

技术标签:

【中文标题】当 testes 函数调用 AppDelegate + managed Object 时单元测试崩溃【英文标题】:Unit Test Crash when the tested function calls AppDelegate + managedObject 【发布时间】:2015-02-13 17:36:34 【问题描述】:

我有以下问题: 我正在快速编写一个应用程序。我有一个托管对象(称为 Category)的类函数(mapCategories),我想对它进行单元测试(XCTest)。

myCategoryFunction 获取一个 NSDictionary 并将其内容映射到一个类别列表 [Category] ​​并返回它。要进行映射,我必须使用以下代码创建 Category 对象:

    class func mapCategories(myDictionary: NSDictionary!) -> [Category]
        var categories: [Category] = []
        /* 
              ... some code here.
       */       
                let appDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)

                let managedObjectContext = appDelegate.managedObjectContext
                let entityDescription = NSEntityDescription.entityForName("Category", inManagedObjectContext: managedObjectContext!)
                var category = Category(entity: entityDescription!, insertIntoManagedObjectContext: managedObjectContext!)
      /* 
             ... some code here.
      */       
       return Categories

当我运行应用程序时,代码运行良好并按预期工作,但是当我运行此函数的单元测试时它崩溃了。

第一次我收到以下错误:

出现在以下行:

let appDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)

当我继续执行程序时,它在获取 managedObjectContext 时崩溃,如下所示:

我试图找到解决方案或变通方法并尝试了以下方法:

UIApplication.sharedApplication().delegate as AppDelegate causes EXC_BAD_ACCESS using it on swift unit test

但它没有用。有没有人有可行的解决方案?

提前致谢,

【问题讨论】:

您找到解决方案了吗?我遇到了同样的问题... 不,我没有:(,这就是为什么我在这个问题上加了赏金 您是否已将所有 CoreData 模型添加到您的测试包中? 是的,但没有解决问题 【参考方案1】:

正如堆栈跟踪所示,无条件强制转换(带有 as AppDelegate 的行)失败。您链接到的问题包含此问题的解决方案。

我的猜测是它对您不起作用的原因是因为您忘记从单元测试捆绑目标中删除 AppDelegate.swift。假设您忘记了,您现在有两个 AppDelegate 定义:一个在您的单元测试包中,一个在您的应用程序包中。无条件转换失败,因为您尝试将应用程序中定义的 AppDelegate 转换为单元测试包中定义的 AppDelegate。

要解决此问题,请按住 Control+单击 AppDelegate.swift 并选择 Show File Inspector,然后确保在 Target Memebership 下唯一的复选框位于您的应用程序旁边,并且您的单元测试包旁边没有检查。

您在托管对象上下文中看到的第二个问题只是第一个问题的结果。

【讨论】:

它终于成功了,但是我必须将我想要单元测试的所有方法和类设置为公共,这不是一个好的解决方案,我会暂时这样做,直到找到更好的解决方案.【参考方案2】:

使用 swift2 你不需要公开你的方法和类,你可以使用,

@testable import main module 

唯一需要注意的是,您需要将 Host Application 属性指向主应用程序包,并在您的测试目标构建设置下切换 Enable Testability = Yes

【讨论】:

以上是关于当 testes 函数调用 AppDelegate + managed Object 时单元测试崩溃的主要内容,如果未能解决你的问题,请参考以下文章

如何与 AppDelegate 中的特定视图交互?

从 AppDelegate 调用委托函数不起作用

无法从 AppDelegate 调用 ViewController 方法

appdelegate 中的 NSURLSessionDataTask

Appdelegate.swift 中的调用函数

AppDelegate 从 m File + presentViewController 调用函数