Swift CoreData UnitTest:如何避免EXC_BREAKPOINT [英] Swift CoreData UnitTest: How to avoid EXC_BREAKPOINT

查看:254
本文介绍了Swift CoreData UnitTest:如何避免EXC_BREAKPOINT的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这将是CoreData单元测试中使用swift的常见问题。 EXC_BREAKPOINT异常发生,因为swift的名称空间在正常模块和测试模块之间的差异。我仍然在努力反对这个问题,即使有些解决方案被介绍。



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


  1. 使用具有核心数据的单一应用程序模板创建新项目,使用检查选项。

  2. 运行单元测试。未发生错误。

  3. 将CoreDataSampleTest目标添加到Appdelegate.swift。

  4. 在CoreDataSampleTests.swift中更改testExample(),如下所示。




  func testExample(){
let appDel:AppDelegate = UIApplication.sharedApplication()。作为AppDelegate委托
}





  1. 运行单元测试。发生了EXC_BREAKPOINT。

  2. 在AppDelegate.swift中更改managedObjectModel(),如下所示 Swift无法在Xcode测试中测试核心数据



pre> lazy var managedObjectModel:NSManagedObjectModel = {
//应用程序的管理对象模型。这个属性不是可选的...
let modelURL = NSBundle.mainBundle()。URLForResource(CoreDataSample,withExtension:momd)!
let managedObjectModel = NSManagedObjectModel(contentsOfURL:modelURL)!

//检查我们是否作为测试运行
let environment = NSProcessInfo.processInfo()。environment as [String:AnyObject]
let isTest =(environment [ XCInjectBundle] as?String)?。pathExtension ==xctest

//创建模块名称
let moduleName =(isTest)? CoreDataSampleTests:CoreDataSample

//使用更新的实体类名创建一个新的托管对象模型
var newEntities = [] as [NSEntityDescription]
for )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
} b





  1. 运行单元测试。再次出现EXC_BREAKPOINT。

我想知道的是两件事。


  1. 如何避免EXC_BREAKPOINT异常。测试方法似乎正常工作,但EXC_BREAKPOINT异常暂时停止每个测试方法的过程。我必须每次都恢复。


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

    / li>

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



/ p>

FYI:





编辑:



XCode版本是6.2

解决方案

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




  • 可选:将您的核心数据移动到一个单独的模块Xcode 6.2仍然似乎不喜欢Swift静态库) - 这个提示curtesy的Jessie Squires,



(这不是必须的,但会帮助保持整洁,因为以下步骤涉及使很多事情公开,并且如果你不分离它,它将传播整个项目。)




  • 将@objc(ClassName)添加到所有NSManagedObject类,

  • 将所有NSManagedObject类及其所有包含的属性设为public



你最终应该看起来像这样的实体:

  import Foundation 
import CoreData

@objc(ClassName)
public class ClassName:NSManagedObject {
@NSManaged public var property:Type
}




  • 使您的模型中所有实体的Entity类名称成为对类的简单引用

  • 公开与Core Data位于同一模块中的所有类,方法,属性等,并且要进行单元测试,

  • 从测试目标中删除所有类(即,为每个类的目标成员资格取消测试目标),但将数据模型保留在测试目标中

  • 将您的应用程式汇入测试类别(例如将测试类别中的应用程式名称新增至测试类别)。



在SO回答中的另一种方法此处也有效。



编辑1:添加了关于替代方案的注释。



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


This would be common problem in CoreData unit testing using swift. EXC_BREAKPOINT exception happens due to swift's namespace differences between normal module and test module. I'm still struggling against this issue even though some solutions are introduced.

What I did and my problem is here.

  1. Create new project using the single application template with core data using check option.
  2. Run unit tests. No errors occurred.
  3. Add CoreDataSampleTest target to Appdelegate.swift.
  4. Change testExample() in CoreDataSampleTests.swift as followings.

func testExample() {
    let appDel: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
}

  1. Run unit tests. EXC_BREAKPOINT occurred.
  2. Change managedObjectModel() in AppDelegate.swift as following 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. Run unit tests. EXC_BREAKPOINT occurred again.

What I want to know are two things.

  1. How to avoid EXC_BREAKPOINT exception. Test methods seem to work normally but EXC_BREAKPOINT exception temporary stop the process at every test methods. I have to resume it every time. It very hard to run the test methods.

  2. If I cannot avoid EXC_BREAKPOINT, I want to ignore the EXC_BREAKPOINT exception when executing unit tests.

Any help or suggestion would be helpful for me.

Thanks,

FYI:

Swift cannot test core data in Xcode tests?.

Edit:

XCode Version is 6.2

解决方案

As Wolfgang said I think the Jesse Squires solution works (it does for me) but there are several steps:

  • Optional: Move your Core Data into a separate module (I used a Framework as Xcode 6.2 still seems not to like Swift static libraries) - this tip curtesy of Jessie Squires,

(This is not necessary but will help keep things tidy as the following steps involve making a lot of things public and that will spread through your whole project if you do not separate it out.)

  • add @objc(ClassName) to all your NSManagedObject classes,
  • make all your NSManagedObject classes and all their contained properties public,

You should end up with entities that look like this:

import Foundation
import CoreData

@objc(ClassName)
public class ClassName: NSManagedObject {
    @NSManaged public var property: Type        
}

  • make the Entity Class name for all your entities in your model a simple reference to the class (e.g. ClassName not a AppName.ClassName).
  • make public all classes, methods, properties etc. that are in the same module as Core Data and that you want to unit test,
  • remove all your classes from the test target (i.e. untick the test target in 'Target Membership' for each of them), but leave the data model in the test target,
  • import your app into your test class(es) (e.g. add import AppName to the test class source).

There is an alternative approach in the SO answer here that also works.

Edit 1: Added note about alternative.

Edit 2: Passed on tip to move Core Data into a separate module.

这篇关于Swift CoreData UnitTest:如何避免EXC_BREAKPOINT的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆