Unit testing 如何使用预填充的SQLite文件使用内存存储类型的核心数据模型?

Unit testing 如何使用预填充的SQLite文件使用内存存储类型的核心数据模型?,unit-testing,core-data,Unit Testing,Core Data,我关注的是Ray Wenderlich团队的一个过时项目,该项目通过使用命令行工具应用程序重新填充核心数据支持的应用程序 我已成功预填充了预期实体,并通过执行NSFetchRequest进行了验证 现在,我想在单元测试中使用相同的预填充数据来验证与CoreData的交互是否正确进行。我尝试设置我的mockCoreDataStack子类以使用内存存储,但是当我尝试验证我是否有用于单元测试的预填充数据时,我得到了0的计数 负责与我的应用程序目标(名为CoreDataStack)中的CoreData交

我关注的是Ray Wenderlich团队的一个过时项目,该项目通过使用命令行工具应用程序重新填充
核心数据支持的应用程序

我已成功预填充了预期实体,并通过执行
NSFetchRequest
进行了验证

现在,我想在单元测试中使用相同的预填充数据来验证与
CoreData
的交互是否正确进行。我尝试设置我的mock
CoreDataStack
子类以使用内存存储,但是当我尝试验证我是否有用于单元测试的预填充数据时,我得到了
0
计数

负责与我的应用程序目标(名为
CoreDataStack
)中的
CoreData
交互的类如下所示:

///负责管理与核心数据交互的对象。
内部类CoreDataStack{
//标记:-属性
///用于存储包含核心数据的信息的`NSManagedObjectModel`对象的名称。
私有let modelName:String
///与主队列关联的`NSManagedObjectContext`对象。
内部惰性变量mainContext:NSManagedObjectContext={
返回self.storeContainer.viewContext
}()
///封装应用程序核心数据堆栈的“NSPersistentContainer”对象。
内部惰性var storeContainer:NSPersistentContainer={
let container=NSPersistentContainer(名称:self.modelName)
let directory=NSPersistentContainer.defaultDirectoryURL()
让storeURL=directory.appendingPathComponent(“\(self.modelName.sqlite”)
如果!FileManager.default.fileExists(atPath:(storeURL.path)){
guard let populatedURL=Bundle.main.url(forResource:self.modelName,扩展名为:“sqlite”)else{
fatalError(“填充的.sqlite文件URL无效”)
}
做{
尝试FileManager.default.copyItem(位于:populatedURL,收件人:storeURL)
}抓住{
fatalError(“错误:\(错误)”)
}
}
let description=NSPersistentStoreDescription()
description.url=storeURL
container.persistentStoreDescriptions=[描述]
中的container.loadPersistentStores(completionHandler:{(storeDescription,错误)
如果let error=错误为N错误{
fatalError(“错误:\(错误)”)
}
})
返回容器
}()
//标记:-初始化
///返回“CoreDataStack”的实例。
///-参数modelName:`NSManagedObjectModel`对象的名称,用于存储包含核心数据的信息。
内部初始化(modelName:String){
self.modelName=modelName
}
///尝试通过在“NSManagedObjectContext”中提交对“NSManagedObject”的更改,将项保存到核心数据。
///-参数上下文:应提交其更改的“NSManagedObjectContext”。
内部func saveContext(context:NSManagedObjectContext){
context.perform{
做{
尝试context.save()
}将let错误捕获为NSError{
fatalError(“未解决的错误\(error),\(error.userInfo)”)
}
}
}
}
用于测试的
CoreDataStack
MockCoreDataStack
的子类如下:

内部类MockCoreDataStack:CoreDataStack{
//标记:-初始化
便利初始化(){
self.init(模型名:“货币”)
}
重写初始化(modelName:String){
super.init(modelName:modelName)
let container=NSPersistentContainer(名称:modelName)
let directory=NSPersistentContainer.defaultDirectoryURL()
让storeURL=directory.appendingPathComponent(“\(modelName.sqlite”)
如果!FileManager.default.fileExists(atPath:(storeURL.path)){
guard let populatedURL=Bundle(for:type(of:self)).url(forResource:modelName,带扩展名:“sqlite”)else{
fatalError(“填充的.sqlite文件URL无效”)
}
做{
尝试FileManager.default.copyItem(位于:populatedURL,收件人:storeURL)
}抓住{
fatalError(“错误:\(错误)”)
}
}
let description=NSPersistentStoreDescription()
description.url=storeURL
description.type=nsimemorystoretype
container.persistentStoreDescriptions=[描述]
container.loadPersistentStores{(storeDescription,错误)位于
如果let error=错误为N错误{
fatalError(“未解决的错误\(error),\(error.userInfo)”)
}
}
self.storeContainer=容器
}
}
在我的单元测试目标中,获取请求的结果
count
0
。我希望返回一个由预填充对象数组成的
count
,就像我在应用程序目标中返回
count
时得到的一样


我的错误操作是什么导致我无法返回预期结果?

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

作为内存存储的替代方案,您可以在持久存储和实际使用的上下文之间创建父级
NSManagedObjectContext
。(不过,我不确定这对
NSPersistentContainer
会有什么影响。)

然后,当您想要重置回初始状态时,您只需
rollback()
父上下文即可