【问题标题】:Unit test with example Core Data使用示例核心数据进行单元测试
【发布时间】:2015-07-01 14:19:50
【问题描述】:

这是我的 XCTestCase 课程的开始:

var moc: NSManagedObjectContext!

    override func setUp() {
        super.setUp()

        moc = self.setUpInMemoryManagedObjectContext()
        self.fillManagedObjectContextWithExampleData(moc)
    }

    func setUpInMemoryManagedObjectContext() -> NSManagedObjectContext {

        let modelName = "ProjectApp"
        let modelURL = NSBundle.mainBundle().URLForResource(modelName, withExtension:"momd")!
        let managedObjectModel = NSManagedObjectModel(contentsOfURL: modelURL)!

        let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: managedObjectModel)
        persistentStoreCoordinator.addPersistentStoreWithType(NSInMemoryStoreType, configuration: nil, URL: nil, options: nil, error: nil)

        let managedObjectContext = NSManagedObjectContext()
        managedObjectContext.persistentStoreCoordinator = persistentStoreCoordinator

        return managedObjectContext
    }

    func fillManagedObjectContextWithExampleData(context: NSManagedObjectContext) {
        // var firstSC = NSEntityDescription..insertNewObjectForEntityForName("StaticContent", inManagedObjectContext: context) as! StaticContent
        var staticContentEntity = NSEntityDescription.entityForName("StaticContent", inManagedObjectContext: context)!

        var firstSC = StaticContent(entity: staticContentEntity, insertIntoManagedObjectContext: context)
        firstSC.name = "First Name"

        var secondSC = StaticContent(entity: staticContentEntity, insertIntoManagedObjectContext: context)
        secondSC.name = "Second Name"

        var error: NSError? = nil

        if context.save(&error) {
            return
        }
    }

我只想创建 managedObjectContext(在内存中,仅用于测试)并用示例数据填充它。所以我可以使用:

managedObjectContext.executeFetchRequest(fetchRequest, error: nil) as! [StaticContent]

在我的单元测试中。它会执行,但是当我调用采用 [StaticContent] 的函数时,出现错误:

fatal error: NSArray element failed to match the Swift Array Element type

那么这有什么问题呢?我调用的函数运行良好。当我在我的应用程序中而不是在单元测试中使用它时,我没有问题。那么我做错了什么?

【问题讨论】:

  • 你能把出错的代码贴出来吗?
  • 顺便说一句,这可能与实体的 managedObjectClassName 在您的测试目标中不同:如果您在测试目标中包含您的管理对象子类,它的类名将是 YourTestTarget.StaticContent.. . 可以用这个解决方法解决:gist.github.com/efa85/d82cc8fb0358e970e1e4
  • 谢谢,我在另一个 stackoverflow 问题中找到了类似的代码。我花了一个小时寻找解决方案,然后在我发布我的问题后我找到了它。

标签: ios swift unit-testing core-data nsmanagedobjectcontext


【解决方案1】:

我真的不想回答我的问题,但我找到了答案,我希望帮助其他人。我找到了一部分代码,它根据它们运行的​​目标更改实体类名称。因此,我在创建 NSManagedObjectModel 的位置添加了这些代码行,这会有所帮助:

    // Create the module name
    let moduleName = "ProjectAppTests"

    // 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

    let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: newManagedObjectModel)

不知道为什么在使用 Swift 的 Core Data 中类名如此复杂。但它有帮助,而且现在正在发挥作用。

【讨论】:

  • 这看起来与stackoverflow.com/a/26796626/1187415中提出的解决方案非常相似。
  • 阅读该问题后,我认为最好的解决方案是按照 Christer 的回答中的建议使用 @objc(YourClass)
  • 我试图使用 @objc(YourClass) 但我仍然遇到了问题。
【解决方案2】:

在 Swift 3.0 中:

func setUpInMemoryManagedObjectContext() -> NSManagedObjectContext {
        let moduleName = "Model"
        do {
            let managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
            let modelURL = Bundle.main.url(forResource: moduleName, withExtension:"momd")
            let newObjectModel = NSManagedObjectModel.init(contentsOf: modelURL!)
            let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel : newObjectModel!)
            try  persistentStoreCoordinator.addPersistentStore(ofType: NSInMemoryStoreType, configurationName: nil, at: nil, options: nil)

            managedObjectContext.persistentStoreCoordinator = persistentStoreCoordinator
            return managedObjectContext
        } catch let error as NSError {
            logErr(error.localizedDescription)
            XCTFail()
        }
        XCTFail("failed to created mocked coreData (inMemroy)")
        return NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
    } 
func fillManagedObjectContextWithExampleData(context: NSManagedObjectContext) {
//lets assume you got some Food POJO class
    do {
        let foodJson: NSDictionary = ["id" : "1" , "foodId" : "1" , "displayName": "Pizza"]
        let firstFood = try Food.createOrUpdate(dict: foodJson, inManagedObjectContext: context)
        try  context.save()
        return
    } catch let error as NSError {
        logErr(error.localizedDescription)
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多