【问题标题】:How to expose CoreData to swift package unit tests?如何将 CoreData 暴露给 swift 包单元测试?
【发布时间】:2020-09-30 04:46:56
【问题描述】:

我正在尝试在我的 swift 包中测试 CoreData,因为 SPM 现在支持包括 .xcdatamodel 在内的捆绑资源,但我的测试似乎无法找到我的 NSManagedObjects。从测试中对核心数据进行单元测试的步骤是什么?

当我尝试从测试中创建 NSManagedObject 时出现此错误:

+entityForName: could not locate an entity named 'StriveUser' in this model. (NSInternalInconsistencyException)

我已经三遍检查了命名,一切都是正确的。

我正在从我的测试中创建这样的对象:

let object = NSEntityDescription.insertNewObject(forEntityName: "StriveUser", into: self.inMemoryStore.context)

这是我定位 .xcdatamodel 的代码:

    fileprivate var managedObjectModel: NSManagedObjectModel = {
    guard let managedObjectModel = NSManagedObjectModel.mergedModel(from: [Bundle.main]) else {
        preconditionFailure("Error getting ManagedObjectModel")
    }

    return managedObjectModel
}()

final class InMemoryStore {
    let context: NSManagedObjectContext

    init() {
        let description = NSPersistentStoreDescription()
        description.type = NSInMemoryStoreType
        description.shouldAddStoreAsynchronously = false

        let container = NSPersistentContainer(name: Constants.modelName, managedObjectModel: managedObjectModel)
        container.persistentStoreDescriptions = [description]
        container.loadPersistentStores {_, error in
            if let error = error {
                fatalError("Failed to load store: \(error.localizedDescription)")
            }
        }

        self.context = container.viewContext
    }
}

【问题讨论】:

  • @JoakimDanielson 在我问这个之前我已经尝试过谷歌搜索,我觉得这可能是 SPM 特有的,所以这就是我问的原因
  • 您的 ManagedObjectModel 捆绑包参考需要更新。如果您从 swift 包资源加载,则需要使用 Bundle.module。你需要有一个访问器,它是你的包的一部分,它使用包模块返回模块。
  • @richardpiazza 谢谢先生,如果您想留下这个作为答案,我很乐意接受它

标签: swift unit-testing core-data swift-package-manager


【解决方案1】:

如果您在包清单中声明 5.3 或更高版本的 Swift 工具,您可以将资源与源代码捆绑为 Swift 包。例如,Swift 包可以包含资产目录、故事板等。

定义资源后,将为包创建一个新的静态Bundle 引用。这可以使用Bundle.module 访问。

因此,对于您的ManagedObjectModel,您需要更新捆绑参考。使用它的一个好方法是在你的包中有一个访问器来返回模型。

有关更多信息,您可以查看 Apple 的开发者文档Bundling Resources with a Swift Package

【讨论】:

【解决方案2】:

我遇到了类似的问题,每当我尝试对核心数据模型执行任何操作时,我的应用都会因“未找到 YourManagedObject”错误而崩溃。

当我将核心数据依赖项从 cocoapods 转移到 swift 包管理器时,这种情况就开始发生了。

但这是我的解决方案:

  1. @objc(ManagedObjectName) 添加到我所有的 NSManagedObject 类中
  2. 在核心数据模型编辑器的数据模型检查器中,删除 Current Project Module 并为模块配置使用默认值。
  3. 正如上面的答案所说,在加载 NSManagedObjectModel 时,请确保使用 Bundle.module 而不是 Bundle.main。
  4. 我重写了我们的核心数据堆栈以使用 NSPersistentStore,而不是按照 WWDC 2018 核心数据最佳实践手动设置所有内容(NSPersistentStoreCoordinator、NSManagedObjectContext 等...)

需要注意的几点:

问题不是因为错误的捆绑包,我在迁移到 SPM 时已经应用了该更改。由于某种原因,该应用在运行时找不到我的任何 NSManagedObject 类。

在尝试 #4 之前先尝试 #1 和 #2。我不知道#4 是否有助于解决这个问题,因为当我删除 Current Project Module 时应用程序停止崩溃。不过,它确实清理了很多丑陋的遗留代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-04
    • 2012-12-21
    • 1970-01-01
    • 2011-09-14
    • 1970-01-01
    • 2011-09-07
    • 1970-01-01
    • 2015-10-26
    相关资源
    最近更新 更多