You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编写Core Data Budget类同名检测测试时遇异常问题

问题解决方法

核心问题分析

你遇到的问题根源有两个:

  1. Core Data的NSFetchRequest默认会包含当前context中未保存的内存对象,所以刚创建的Budget实例会被exists函数检测到,导致第一次调用save就触发重复异常。
  2. 你的save方法里调用try save()会无限递归调用自身,最终会引发栈溢出错误。

解决方案步骤

1. 修复exists函数,排除未保存的内存对象

修改exists方法,给fetch请求添加includesPendingChanges = false配置,让查询只读取持久化存储中的数据,忽略context里未保存的临时对象:

private func exists(_ name: String) throws -> Bool {
    let request = Budget.fetchRequest()
    request.predicate = NSPredicate(format: "name = %@", name)
    request.sortDescriptors = []
    request.includesPendingChanges = false // 关键配置:仅查询已持久化的数据
    let budgets = try viewContext.fetch(request)
    return !budgets.isEmpty
}

2. 修复save方法的无限递归问题

将save方法中调用的try save()改为调用父类的save方法,避免无限递归:

override func save() throws {
    if try exists(name ?? "") {
        throw BudgetError.duplicateName
    } else {
        try super.save() // 调用父类的save方法,而非自身
    }
}

3. 优化测试代码

移除不必要的refreshAllObjects调用(会重置未保存的对象属性),测试代码修改为:

func test_Throws_Duplicate_Name_Exception() throws {
    var thrownError: Error?
    
    let budget = Budget(context: CoreDataProvider.shared.viewContext)
    budget.name = "Car Rental"
    
    try budget.save() // 第一次save成功
    
    // 再次调用save,验证是否抛出重复异常
    XCTAssertThrowsError(try budget.save()) {
        thrownError = $0
    }
    
    XCTAssertEqual(thrownError as? BudgetError, .duplicateName)
}

内容的提问来源于stack exchange,提问作者john doe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 00:10:52