当我尝试将 Core Data 与 NSInMemoryStoreType
一起用于单元测试时,我总是会收到此错误:
Failed to find a unique match for an NSEntityDescription to a managed object subclass
这是我创建核心数据堆栈的对象:
public enum StoreType {
case sqLite
case binary
case inMemory
.................
}
public final class CoreDataStack {
var storeType: StoreType!
public init(storeType: StoreType) {
self.storeType = storeType
}
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "Transaction")
container.loadPersistentStores(completionHandler: { (description, error) in
if let error = error {
fatalError("Unresolved error \(error), \(error.localizedDescription)")
} else {
description.type = self.storeType.type
}
})
return container
}()
public var context: NSManagedObjectContext {
return persistentContainer.viewContext
}
public func reset() {
for store in persistentContainer.persistentStoreCoordinator.persistentStores {
guard let url = store.url else { return }
try! persistentContainer.persistentStoreCoordinator.remove(store)
try! FileManager.default.removeItem(at: url)
}
}
}
这就是我在单元测试项目中使用它的方式:
class MyTests: XCTestCase {
var context: NSManagedObjectContext!
var stack: CoreDataStack!
override func setUp() {
stack = CoreDataStack(storeType: .inMemory)
context = stack.context
}
override func tearDown() {
stack.reset()
context = nil
}
}
从我读到的here这似乎是我遇到的同一个问题,我必须在每次测试后清理所有东西,我(认为)我正在这样做。
我没有正确清理吗?还有其他方法吗?
最佳答案
CoreDataStack
类是否已在您的应用程序中初始化?例如,在 AppDelegate
类中?当单元测试运行时,它将在测试运行前的某个时间初始化 AppDelegate
。我相信这样一来,您的测试就可以根据 @testable import MyApp
行从应用程序调用任何内容以对其进行测试。如果您在 MyTests
中通过 AppDelegate
和 初始化 Core Data 堆栈,那么您将加载 Core Data 堆栈两次。
请注意,拥有两个或多个 NSPersistentContainer
实例意味着两个或多个 NSManagedObjectModel
实例将被加载到内存中,这就是导致问题的原因。这两个模型都在运行时提供额外的 NSManagedObject
子类。当您随后尝试使用这些子类之一时,运行时不知道要使用哪个(即使它们相同,它只是看到它们具有相同的名称)。我认为如果 NSManagedObjectModel
能够处理这种情况会更好,但目前由开发人员确保加载的实例不会超过一个。
关于ios - 如何将核心数据用于主要应用程序和单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55088704/