ios - 如何将核心数据用于主要应用程序和单元测试?

标签 ios swift unit-testing core-data

当我尝试将 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/

相关文章:

ios - 如何快速导入自定义框架内的类

swift - 如果 (Bools = true) 不执行 -Swift

swift - swift 中的上下文是什么?

java - JUnit 中的错误和失败有什么区别?

python - 如何使用 MagicMock 欺骗 issubclass 检查?

java - 通过 maven surefire-report 在单个文件中以汇总格式执行单元测试类中的测试执行时间

javascript - WKWebView - Javascript 确认和警报不起作用

objective-c - 我想使用 -> 运算符设置 ivar

objective-c - 插入 UINavigationController 时隐藏 FB Friend Picker ViewController 导航栏

ios - 快速裁剪用相机拍摄的图像