我正在关注来自Ray Wenderlich团队的过时tutorial,该团队使用命令行工具应用程序完成了Core Data
支持的应用程序的重新填充。
我已成功预先填充了目标实体,并通过执行NSFetchRequest
进行了验证。
现在,我想在单元测试中使用相同的预填充数据来验证我与CoreData
的互动是否正确发生。我尝试将我的模拟CoreDataStack
子类设置为使用内存存储,但是当我尝试验证我有预先填充的数据以便在我的单元测试中使用时,我得到的count
{ {1}}。
负责与我的应用程序目标0
中的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)")
}
}
}
}
,CoreDataStack
的子类如下:
MockCoreDataStack
在我的单元测试目标中,我的获取请求的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 :(得分:0)
内存商店不使用商店网址。它只是在内存中创建一个空存储。
作为内存存储的替代方法,您可以在持久存储和实际使用的上下文之间创建父NSManagedObjectContext
。 (但我不确定NSPersistentContainer
会如何发挥作用。)
然后,当您想要重置回初始状态时,您只需rollback()
父上下文。