ios - Swift 核心数据单元测试 : How to avoid EXC_BREAKPOINT

标签 ios xcode swift core-data

这将是使用 swift 的 CoreData 单元测试中的常见问题。 EXC_BREAKPOINT 异常是由于正常模块和测试模块之间的 swift namespace 差异而发生的。尽管介绍了一些解决方案,但我仍在努力解决这个问题。

我做了什么,我的问题就在这里。

  1. 使用带有检查选项的核心数据的单个应用程序模板创建新项目。
  2. 运行单元测试。没有发生错误。
  3. 将 CoreDataSampleTest 目标添加到 Appdelegate.swift。
  4. 更改 CoreDataSampleTests.swift 中的 testExample() 如下。
func testExample() {
    let appDel: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
}
  1. 运行单元测试。发生 EXC_BREAKPOINT。
  2. 按以下方式更改 AppDelegate.swift 中的 managedObjectModel() Swift cannot test core data in Xcode tests? .
lazy var managedObjectModel: NSManagedObjectModel = {
    // The managed object model for the application. This property is not optional...
    let modelURL = NSBundle.mainBundle().URLForResource("CoreDataSample", withExtension: "momd")!
    let managedObjectModel = NSManagedObjectModel(contentsOfURL: modelURL)!

    // Check if we are running as test or not
    let environment = NSProcessInfo.processInfo().environment as [String : AnyObject]
    let isTest = (environment["XCInjectBundle"] as? String)?.pathExtension == "xctest"

    // Create the module name
    let moduleName = (isTest) ? "CoreDataSampleTests" : "CoreDataSample"

    // Create a new managed object model with updated entity class names
    var newEntities = [] as [NSEntityDescription]
    for (_, entity) in enumerate(managedObjectModel.entities) {
        let newEntity = entity.copy() as NSEntityDescription
        newEntity.managedObjectClassName = "\(moduleName).\(entity.name)"
        newEntities.append(newEntity)
    }
    let newManagedObjectModel = NSManagedObjectModel()
    newManagedObjectModel.entities = newEntities

    return newManagedObjectModel
}()
  1. 运行单元测试。 EXC_BREAKPOINT 再次发生。

我想知道两件事。

  1. 如何避免 EXC_BREAKPOINT 异常。测试方法似乎正常工作,但 EXC_BREAKPOINT 异常会在每个测试方法处临时停止该过程。我每次都必须恢复它。运行测试方法非常困难。

  2. 如果无法避免 EXC_BREAKPOINT,我想在执行单元测试时忽略 EXC_BREAKPOINT 异常。

任何帮助或建议都会对我有帮助。

谢谢,

仅供引用:

Swift cannot test core data in Xcode tests? .

编辑:

XCode 版本为 6.2

最佳答案

正如 Wolfgang 所说,我认为 Jesse Squires 解决方案有效(它对我有效),但有几个步骤:

  • 可选:将您的核心数据移动到一个单独的模块中(我使用了一个框架,因为 Xcode 6.2 似乎仍然不喜欢 Swift 静态库)- 此提示由 Jessie Squires 提供,

(这不是必需的,但有助于保持整洁,因为以下步骤涉及公开很多内容,如果您不将其分开,这些内容将传播到整个项目。)

  • 将@objc(ClassName) 添加到所有 NSManagedObject 类中,
  • 将所有 NSManagedObject 类及其所有包含的属性公开,

您最终应该得到如下所示的实体:

import Foundation
import CoreData

@objc(ClassName)
public class ClassName: NSManagedObject {
    @NSManaged public var property: Type        
}
  • 使模型中所有实体的实体类名称成为对该类的简单引用(例如,ClassName 而不是 AppName.ClassName)。
  • 公开所有与 Core Data 在同一模块中并且您想要进行单元测试的类、方法、属性等,
  • 从测试目标中删除所有类(即取消勾选每个类的“目标成员资格”中的测试目标),但将数据模型保留在测试目标中,
  • 将您的应用程序导入您的测试类(例如,将 import AppName 添加到测试类源)。

SO 答案中有一个替代方法 here这也有效。

编辑 1:添加了关于备选方案的注释。

编辑 2:传递了将核心数据移至单独模块的提示。

关于ios - Swift 核心数据单元测试 : How to avoid EXC_BREAKPOINT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29313645/

相关文章:

iphone - 应用程序在 super dealloc 方法中崩溃

macos - NSWindow 调整大小后 NSView 变形

swift 从 firebase 检索快照节点的最佳方法是什么

ios - ionic 找不到平台

ios - 使用json以快速登录形式从mysql获取登录数据

ios - 如何防止 iOS 应用程序上的 Mach-O 链接器错误?

ios - 在 iOS 中使用预定义的文本从 App 打开电子邮件

iphone - 在编译 iPhone 应用程序时,armv7 相对于 armv6 的优势是什么?

ios - Q :Controller present 2 second ,如何让它看起来只有一个转换?

ios - 将 Sprite Kit 与空应用程序混合