2017-04-11 31 views
0

我正在关注来自Ray Wenderlich团队的过时tutorial,该团队使用命令行工具应用程序遍历了应用Core Data-backed应用程序的重新填充。如何使用核心数据模型与内存中的存储类型使用预填充的SQLite文件?

我已成功预先填充预定实体,并通过执行NSFetchRequest进行验证。

现在,我想在我的单元测试中使用相同的预填充数据来验证我与CoreData的交互正确发生。我试图设置我的模拟CoreDataStack子类使用内存中的存储,但是当我试图验证我有我的单元测试中使用的预填充数据时,我得到0count

类负责与我的应用程序的目标CoreData互动,名为CoreDataStack,如下:

/// The object that is responsible for managing interactions with Core Data. 
internal class CoreDataStack { 

    // MARK: - Properties 

    /// The name of the `NSManagedObjectModel` object used for storing information with Core Data. 
    private let modelName: String 

    /// The `NSManagedObjectContext` object that is associated with the main queue. 
    internal lazy var mainContext: NSManagedObjectContext = { 
     return self.storeContainer.viewContext 
    }() 

    /// The `NSPersistentContainer` object that encapsulates the application's Core Data stack. 
    internal lazy var storeContainer: NSPersistentContainer = { 
     let container = NSPersistentContainer(name: self.modelName) 
     let directory = NSPersistentContainer.defaultDirectoryURL() 
     let storeURL = directory.appendingPathComponent("\(self.modelName).sqlite") 
     if !FileManager.default.fileExists(atPath: (storeURL.path)) { 
      guard let populatedURL = Bundle.main.url(forResource: self.modelName, withExtension: "sqlite") else { 
       fatalError("Invalid populated .sqlite file URL") 
      } 
      do { 
       try FileManager.default.copyItem(at: populatedURL, to: storeURL) 
      } catch { 
       fatalError("Error: \(error)") 
      } 
     } 
     let description = NSPersistentStoreDescription() 
     description.url = storeURL 
     container.persistentStoreDescriptions = [description] 
     container.loadPersistentStores(completionHandler: { (storeDescription, error) in 
      if let error = error as NSError? { 
       fatalError("Error: \(error)") 
      } 
     }) 
     return container 
    }() 

    // MARK: - Initialization 

    /// Returns an instance of `CoreDataStack`. 
    /// - parameter modelName: The name of the `NSManagedObjectModel` object used for storing information with Core Data. 
    internal init(modelName: String) { 
     self.modelName = modelName 
    } 

    /// Attempts to save items to Core Data by committing changes to `NSManagedObject`s in a `NSManagedObjectContext`. 
    /// - parameter context: The `NSManagedObjectContext` of which changes should be committed. 
    internal func saveContext(_ context: NSManagedObjectContext) { 
     context.perform { 
      do { 
       try context.save() 
      } catch let error as NSError { 
       fatalError("Unresolved error \(error), \(error.userInfo)") 
      } 
     } 
    } 
} 

CoreDataStackMockCoreDataStack的子类,用于测试如下:

internal class MockCoreDataStack: CoreDataStack { 

    // MARK: - Initialization 

    convenience init() { 
     self.init(modelName: "Currency") 
    } 

    override init(modelName: String) { 
     super.init(modelName: modelName) 
     let container = NSPersistentContainer(name: modelName) 
     let directory = NSPersistentContainer.defaultDirectoryURL() 
     let storeURL = directory.appendingPathComponent("\(modelName).sqlite") 
     if !FileManager.default.fileExists(atPath: (storeURL.path)) { 
      guard let populatedURL = Bundle(for: type(of: self)).url(forResource: modelName, withExtension: "sqlite") else { 
       fatalError("Invalid populated .sqlite file URL") 
      } 
      do { 
       try FileManager.default.copyItem(at: populatedURL, to: storeURL) 
      } catch { 
       fatalError("Error: \(error)") 
      } 
     } 
     let description = NSPersistentStoreDescription() 
     description.url = storeURL 
     description.type = NSInMemoryStoreType 
     container.persistentStoreDescriptions = [description] 
     container.loadPersistentStores { (storeDescription, error) in 
      if let error = error as NSError? { 
       fatalError("Unresolved error \(error), \(error.userInfo)") 
      } 
     } 
     self.storeContainer = container 
    } 
} 

产生的count我的提取请求的单元测试目标是0。我希望返回包含预填充对象数量的count,就像我在返回应用程序目标中的count时所得到的一样。

我做了什么不正确的事情导致我没有返回预期的结果?

回答

0

内存中存储不使用商店URL。它只是在内存中创建一个空的商店。

作为内存存储的替代方案,您可以在持久性存储和实际使用的上下文之间创建父项NSManagedObjectContext。 (但是我不知道NSPersistentContainer会怎么样)

然后当你想重置回你的初始状态时,你可以只需rollback()父上下文。

相关问题