Ios 在后台进程中使用模拟核心数据容器
我用使用核心数据的Swift iOS应用程序实现了单元测试,但我在通过单元测试方面遇到了困难。我引用了下面链接的指南和一些堆栈溢出线程,但仍然有问题 该应用程序在实际构建时运行时没有缺陷,但测试失败了,这让我相信我在集成模拟核心数据容器和后台持久性容器时弄糟了。然而,我似乎不知道我在这里错在哪里,所以任何建议都是非常感谢的 我很抱歉,如果我的帖子缺少任何关键细节,但我会在必要时添加它们 主要参考资料: 测试代码 控制器类Ios 在后台进程中使用模拟核心数据容器,ios,swift,unit-testing,core-data,Ios,Swift,Unit Testing,Core Data,我用使用核心数据的Swift iOS应用程序实现了单元测试,但我在通过单元测试方面遇到了困难。我引用了下面链接的指南和一些堆栈溢出线程,但仍然有问题 该应用程序在实际构建时运行时没有缺陷,但测试失败了,这让我相信我在集成模拟核心数据容器和后台持久性容器时弄糟了。然而,我似乎不知道我在这里错在哪里,所以任何建议都是非常感谢的 我很抱歉,如果我的帖子缺少任何关键细节,但我会在必要时添加它们 主要参考资料: 测试代码 控制器类 类测量控制器{ //标记:-属性 // 私有let persistentC
类测量控制器{
//标记:-属性
//
私有let persistentContainer:NSPersistentContainer!
私有变量fetchedResultsController:NSFetchedResultsController!
lazy var backgroundMOC:NSManagedObjectContext={
返回self.persistentContainer.newBackgroundContext()
}()
//默认情况下设置为标准持久性容器
init(时态:tense,persistentContainer:NSPersistentContainer){
self.persistentContainer=persistentContainer
self.persistentcainer.viewContext.automaticallyMergesChangesFromParent=true
重新加载所有本地数据(for:tense)
}
便利初始化(时态:时态){
让appDelegate=UIApplication.shared.delegate作为?appDelegate else{
fatalError(“无法设置托管对象上下文”)
}
init(时态:tense,persistentContainer:appDelegate.persistenceContainer)
}
func getMealCount()->Int{
返回fetchedResultsController.FetchedObject?计数??0
}
func getfine(在indexPath:indexPath)->fine{
返回fetchedResultsController.object(位于:indexPath)
}
//布尔值决定是显示历史数据还是显示未来数据
func重新加载所有本地数据(对于时态:tense){
let fetchRequest:NSFetchRequest=deal.fetchRequest()
//设置谓词等。
//
fetchedResultsController=NSFetchedResultsController(fetchRequest:fetchRequest,managedObjectContext:backgroundMOC,sectionNameKeyPath:nil,cacheName:nil)//是否向此添加缓存?
做{
请尝试fetchedResultsController.performFetch()
}捕捉错误{
//
}
}
//拯救
func SAVELOCALMEIN(mealType:Int16,date:NSDate,mealDescription:String,servings:Int16,image:UIImage?,收藏:Bool,注释:String?=nil,recipeUID:String?=nil)->MEIN{
//制作新餐标
let-mean=mean(实体:mean.entity(),insertInto:backgroundMOC)
//调用helper func和result
返回保存(上下文:backgroundMOC,膳食:膳食,膳食ID:nil,膳食类型:膳食类型,日期:日期,膳食描述:膳食描述,服务:服务,图像:图像,收藏夹:收藏夹,注释:注释,收件人ID:recipeUID)
}
私有函数保存(上下文:NSManagedObjectContext,膳食:膳食,膳食ID:String?,膳食类型:Int16,日期:NSDate,膳食描述:String,服务:Int16,图像:UIImage?,收藏夹:Bool,注释:String?=nil,recipeUID:String?=nil)->膳食{
//设置属性
//
做{
试试backgroundMOC.save()
回餐
}将let错误捕获为NSError{
打印(“无法保存。\(错误)”)
归零
}
}
class MealTests: XCTestCase {
var sut: MealController!
lazy var managedObjectModel: NSManagedObjectModel = {
let managedObjectModel = NSManagedObjectModel.mergedModel(from: [Bundle(for: type(of: self))])!
return managedObjectModel
}()
lazy var mockPersistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "WeeklyModel", managedObjectModel: self.managedObjectModel)
let description = NSPersistentStoreDescription()
description.type = NSInMemoryStoreType
description.shouldAddStoreAsynchronously = false
container.persistentStoreDescriptions = [description]
container.loadPersistentStores {(description, error) in
//Double check to confirm that date store is in memory
precondition(description.type == NSInMemoryStoreType)
//Check for errors
if let error = error {
fatalError("Creating an in-memory coordinator failed")
}
}
return container
}()
override func setUp() {
super.setUp()
sut = MealController(tense: .all, persistentContainer: mockPersistentContainer)
}
func test_CreatingNewMeal_IsNotNilAndPropertiesSetCorrectly() {
let mealType = Int16(1)
let date = NSDate(timeIntervalSinceNow: 0.0)
let mealDescription = "Testy McTestFace"
let servings = Int16(1)
let image = UIImage(named: "Recipe")
let favorite = false
let meal = sut.saveLocalMeal(mealType: mealType, date: date, mealDescription: mealDescription, servings: servings, image: image, favorite: favorite)
//Test meal is not nil
XCTAssertNotNil(meal, "Should not be nil")
//Testing creating meal sets all properties correctly
XCTAssertEqual(meal?.meal, mealType)
}
class MealController {
//MARK: - Properties
//<...>
private let persistentContainer: NSPersistentContainer!
private var fetchedResultsController: NSFetchedResultsController<Meal>!
lazy var backgroundMOC: NSManagedObjectContext = {
return self.persistentContainer.newBackgroundContext()
}()
//Set to standard persistence container by default
init(tense: Tense, persistentContainer: NSPersistentContainer) {
self.persistentContainer = persistentContainer
self.persistentContainer.viewContext.automaticallyMergesChangesFromParent = true
reloadAllLocalData(for: tense)
}
convenience init(tense: Tense) {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
fatalError("Could not set Managed Object Context")
}
self.init(tense: tense, persistentContainer: appDelegate.persistenceContainer)
}
func getMealCount() -> Int {
return fetchedResultsController.fetchedObjects?.count ?? 0
}
func getMeal(at indexPath: IndexPath) -> Meal {
return fetchedResultsController.object(at: indexPath)
}
//The boolean determines whether historical or future data is shown
func reloadAllLocalData(for tense: Tense){
let fetchRequest: NSFetchRequest<Meal> = Meal.fetchRequest()
//Setting predicate, etc.
//<...>
fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: backgroundMOC, sectionNameKeyPath: nil, cacheName: nil)//Add cache to this?
do {
try fetchedResultsController.performFetch()
} catch let error {
//<...>
}
}
//Saving
func saveLocalMeal(mealType: Int16, date: NSDate, mealDescription: String, servings: Int16, image: UIImage?, favorite: Bool, comment: String? = nil, recipeUID: String? = nil) -> Meal? {
//Make new meal object
let meal = Meal(entity: Meal.entity(), insertInto: backgroundMOC)
//Call helper func and result result
return save(context: backgroundMOC, meal: meal, mealUID: nil, mealType: mealType, date: date, mealDescription: mealDescription, servings: servings, image: image, favorite: favorite, comment: comment, recipeUID: recipeUID)
}
private func save(context: NSManagedObjectContext, meal: Meal, mealUID: String?, mealType: Int16, date: NSDate, mealDescription: String, servings: Int16, image: UIImage?, favorite: Bool, comment: String? = nil, recipeUID: String? = nil) -> Meal? {
//Setting properties
//<...>
do {
try backgroundMOC.save()
return meal
} catch let error as NSError {
print("Could not save. \(error)")
return nil
}
}