Swift核心数据单元测试:如何避免EXC_BREAKPOINT

时间:2015-03-28 04:19:01

标签: ios xcode swift core-data

这是使用swift进行CoreData单元测试时的常见问题。 EXC_BREAKPOINT异常是由于普通模块和测试模块之间的swift命名空间差异而发生的。即使引入了一些解决方案,我仍然在努力解决这个问题。

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

  1. 使用带有核心数据的单个应用程序模板使用check选项创建新项目。
  2. 运行单元测试。没有发生错误。
  3. 将CoreDataSampleTest目标添加到Appdelegate.swift。
  4. 在CoreDataSampleTests.swift中更改testExample(),如下所示。
  5. 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?
    3. 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再次发生。
      2. 我想知道的是两件事。

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

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

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

          谢谢,

          供参考:

          Swift cannot test core data in Xcode tests?

          编辑:

          XCode版本是6.2

2 个答案:

答案 0 :(得分:3)

正如沃尔夫冈所说,我认为Jesse Squires解决方案有效(对我而言),但有几个步骤:

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

(这不是必要的,但有助于保持整洁,因为以下步骤涉及将很多事情公之于众,如果你不把它分开,它将在你的整个项目中传播。)

  • 将@objc(ClassName)添加到所有NSManagedObject类
  • 将所有NSManagedObject类及其所有包含的属性设为public,

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

import Foundation
import CoreData

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

SO答案here中有另一种方法也可以。

编辑1:添加了关于替代方案的说明。

编辑2:通过提示将Core Data移动到一个单独的模块中。

答案 1 :(得分:2)

您可以找到Jesse发布的解决方案:http://www.jessesquires.com/swift-coredata-and-testing/