2017-04-11 9 views
0

私は、コマンドラインツールアプリケーションを使用してCore Dataが返されたアプリケーションの再移植を行うRay Wenderlichチームの古いtutorialに従っています。事前投入されたSQLiteファイルを使用して、メモリ内ストア型のコアデータモデルを使用する方法?

NSFetchRequestを実行して検証された目的のエンティティには、正常に事前入力されました。

ユニットテストで同じ事前入力データを使用して、CoreDataとのやりとりが正しく行われていることを確認します。私は嘲笑したCoreDataStackサブクラスをインメモリストアを使用するように設定しようとしましたが、私のユニットテストで使用するために事前入力されたデータがあることを確認しようとすると、count0になりました。

CoreDataStackという名前の自分のアプリケーションのターゲットにCoreDataとの相互作用を担当するクラスは、次のとおりです。

/// 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()にするだけです。

関連する問題