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

Moq Callback缓存旧变量值导致单元测试失败原因咨询

原因说明

这个行为完全符合C#语言和Moq框架的运行逻辑,不存在所谓的"缓存异常",是两个核心机制共同作用的结果:

  • 第二次调用ReusableMethod时,根本不会更新Mock的回调绑定
    查看方法内的分支逻辑:只有当传入的p参数为null时,才会新建IMyWebSocket的Mock实例、为send方法绑定Callback逻辑。第二次调用时你传入了第一次生成的PostMan实例,p == null的判断不成立,因此不会执行任何Mock配置操作,实例持有的还是第一次创建的Mock对象,绑定的Callback也从未被替换。
  • Lambda闭包捕获的是作用域内的变量本身,而非变量的值,且只会捕获定义时所在作用域的变量
    第一次调用ReusableMethod时,你在if块中定义的Callback lambda,捕获的是本次方法调用传入的testMailItem参数变量。这个变量是第一次方法调用栈上独立的值类型变量,值始终为0,它和测试方法里的局部变量testMailItem、第二次调用ReusableMethod时传入的testMailItem参数是三个完全独立、互不关联的变量。

完整执行流程对应报错逻辑

  1. 第一次调用ReusableMethod(0, null):进入if分支创建Mock,绑定Callback(捕获当前方法的testMailItem参数,值为0),随后调用p.MailIt(0)触发回调,断言0 == 0验证通过,返回生成的PostMan实例。
  2. 测试方法内将局部变量testMailItem赋值为7,调用ReusableMethod(7, p):因为p不为空,直接跳过Mock配置逻辑,调用p.MailIt(7)触发send方法。此时执行的还是第一次绑定的Callback,它读取的是自身捕获的、第一次方法调用的testMailItem变量(值为0),因此断言时对比预期值0和实际传入值7,抛出你看到的错误。

产生预期偏差的核心原因是混淆了三个同名的不同变量,Callback从始至终只和它被定义时捕获的那个参数变量绑定,和另外两个同名变量没有任何关联。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 17:54:30