2017-04-11 36 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()父上下文。

相關問題