核心数据测试不会导致持久性存储错误

时间:2019-07-03 05:02:12

标签: swift core-data xctest

当我使用以下测试测试Core数据时,如果符合期望(如图所示),则会收到错误消息“此NSPersistentStoreCoordinator没有永久存储(未知)。它无法执行保存操作。” 但是,我的打印日志的输出确认该便笺已添加到我的核心数据存储中。

override func setUp() {
    super.setUp()
    managedObjectModel = NSManagedObjectModel.mergedModel(from: nil)
    storeCordinator = NSPersistentStoreCoordinator(managedObjectModel: managedObjectModel)
    do {
        store = try storeCordinator.addPersistentStore(
            ofType: NSInMemoryStoreType, configurationName: nil, at: nil, options: nil)
    } catch {
        XCTFail("Failed to create a persistent store, \(error)")
    }
}

func testCoreDataAddNoteItem() {
    let expectation = XCTestExpectation(description: #function)
    let managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
    managedObjectContext.persistentStoreCoordinator = storeCordinator
    let entity = NSEntityDescription.entity(forEntityName: Constants.entityName, in: managedObjectContext)!
    let coreDataManager = CoreDataManager(mainObjectContext: managedObjectContext, entity: entity)
    let note = Note(entity: entity, insertInto: coreDataManager.getMainManagedObjectContext()!)
    note.contents = "Contents"
    note.title = "title"
    note.createdAt = Date()
    note.contents = "contents"
    note.emoji = String(describing: 0x1F601)
    note.updatedAt = Date()

    coreDataManager.getMainManagedObjectContext()!.performAndWait {
        coreDataManager.saveContext()
    }

    coreDataManager.getMainManagedObjectContext()!.performAndWait {
        let request = NSFetchRequest<Note>(entityName: Constants.entityName)
        request.returnsObjectsAsFaults = false
        do {
            let result = try managedObjectContext.fetch(request)
            for data in result as [NSManagedObject] {
                print(data.value(forKey: "title") as! String)
                print(data.value(forKey: "title") as! String == "title")
                XCTAssertEqual(data.value(forKey: "title") as! String, "title")
                expectation.fulfill()

            }
        } catch {
            print("Failed")
        }
    }

    wait(for: [expectation], timeout: 3.0)
}

作为参考,这是我的核心数据堆栈:

public protocol CoreDataManagerProtocol {
    func saveContext ()
    init()
    func getMainManagedObjectContext() -> NSManagedObjectContext?
    func getChildManagedObjectContext() -> NSManagedObjectContext?
    func saveContext (_ context: NSManagedObjectContext)
}

class CoreDataManager: CoreDataManagerProtocol {

    // MARK: Properties
    private let modelName: String
//    private var entity: NSEntityDescription! = nil

//    lazy var managedObjectContext: NSManagedObjectContext = {
//        // The alternative to this is to set up our own store
//        return (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
//    }()

    private var managedObjectContext: NSManagedObjectContext! = nil

    private(set) lazy var childManagedObjectContext: NSManagedObjectContext = {
        // Initialize Managed Object Context
        let myChildManagedObjectContext = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)

        // Configure Managed Object Context
        myChildManagedObjectContext.parent = self.managedObjectContext

        return myChildManagedObjectContext
    }()

    // NSPersistentContainer - hides implementation details of how persistent stores are configured
    lazy var storeContainer: NSPersistentContainer = {
        let container = NSPersistentContainer(name: Constants.modelName)
        container.loadPersistentStores { (storeDescription, error) in
            if let error = error as NSError? {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        }
        return container
    }()


    func getMainManagedObjectContext() -> NSManagedObjectContext? {
        return managedObjectContext
    }

    func getChildManagedObjectContext() -> NSManagedObjectContext? {
        return childManagedObjectContext
    }

    init (mainObjectContext: NSManagedObjectContext, entity: NSEntityDescription) {
        self.modelName = Constants.modelName // "EmojiNotes"
        managedObjectContext = mainObjectContext
//        self.entity = NSEntityDescription.entity(forEntityName: Constants.entityName, in: managedObjectContext)!
//        self.entity = entity
    }

    required init() {
        managedObjectContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
        self.modelName = Constants.modelName
    }

    func saveContext (_ context: NSManagedObjectContext) {
        // performblock and execute on correct thread
        context.perform {
            if context.hasChanges {
                do {

                    try context.save()
                    // inform listeners that we have updated the model
                    // NotificationCenter.default.post(name: Notification.Name.dataModelDidUpdateNotification, object: self, userInfo: nil)

                } catch let error as NSError {
                    print("Unresolved error \(error), \(error.userInfo)")
                }
            }
        }
    }

    func saveContext () {

        if childManagedObjectContext.hasChanges {
            childManagedObjectContext.performAndWait {
                do {

                    try childManagedObjectContext.save()
                    // inform listeners that we have updated the model
                    // NotificationCenter.default.post(name: Notification.Name.dataModelDidUpdateNotification, object: self, userInfo: nil)

                } catch let error as NSError {
                    print("Unresolved error \(error), \(error.userInfo)")
                }
            }
        }
        print (managedObjectContext.persistentStoreCoordinator?.persistentStores.count)
        if managedObjectContext.hasChanges {
            managedObjectContext.perform {
            do {

                try self.managedObjectContext.save()
                // inform listeners that we have updated the model
                // NotificationCenter.default.post(name: Notification.Name.dataModelDidUpdateNotification, object: self, userInfo: nil)

            } catch let error as NSError {
                print("Unresolved error \(error), \(error.userInfo)")
            }
            }
        }

    }


}

我找到了解决方案:

  

尝试! coreDataManager.getChildManagedObjectContext()?. save()

如何保存而不会出现错误。

那为什么是解决方案?

0 个答案:

没有答案