Как использовать Core Data для основного приложения и модульных тестов? - PullRequest
1 голос
/ 10 марта 2019

Когда я пытаюсь использовать 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
    }
}

Из того, что я прочитал здесь , что, кажется, та же проблема, что и у меня, я долженочищайте все после каждого теста, который я (думаю) делаю.

Я не убираюсь правильно?Есть ли другой способ сделать это?

1 Ответ

0 голосов
/ 12 марта 2019

Класс CoreDataStack инициализирован в вашем приложении? Например, в классе AppDelegate? Когда выполняется модульный тест, он инициализирует AppDelegate за некоторое время до запуска теста. Я полагаю, что это так, что ваши тесты могут вызывать что угодно из приложения, чтобы проверить его, согласно строке @testable import MyApp. Если вы инициализируете стек основных данных через ваши AppDelegate и в MyTests, то вы будете загружать стек основных данных дважды.

Следует отметить, что наличие двух или более экземпляров NSPersistentContainer означает, что два или более экземпляров NSManagedObjectModel будут загружены в память, что и является причиной проблемы. Обе модели предоставляют дополнительные NSManagedObject подклассы во время выполнения. Когда вы затем пытаетесь использовать один из этих подклассов, среда выполнения не знает, какой из них использовать (даже если они идентичны, просто видит, что они имеют одинаковые имена). Я думаю, что было бы лучше, если бы NSManagedObjectModel мог справиться с этим делом, но в настоящее время разработчик должен убедиться, что никогда не будет загружено более одного экземпляра.

...