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

Autofixture.NSubstitute未冻结依赖无法校验调用记录如何处理?

问题原因

AutoFixture 默认行为下,每次请求同类型实例、或者解析构造函数依赖时,都会生成一个全新的实例。Freeze<T>()的核心作用是将首次生成的T实例缓存,后续所有对T类型的请求都会返回这个唯一的缓存实例。

你当前代码的执行逻辑存在实例不匹配的问题:

  1. 调用fixture.Create<Sut>()创建被测系统时,AutoFixture自动生成了第一个IDep模拟实例注入到Sut构造函数,这个实例的Click方法确实被调用了
  2. 后续执行fixture.Freeze<IDep>()时,因为之前没有缓存过IDep实例,所以生成了第二个全新的IDep模拟实例,这个实例从未被Sut调用,自然无法通过调用校验。

正确实现方式

方案1:提前Freeze依赖(最常用)

将Freeze操作移到创建Sut实例之前,保证Sut注入的实例和你校验的实例是同一个:

var fixture = new Fixture().Customize(
  new AutoNSubstituteCustomization { ConfigureMembers = true }
);

// 先冻结依赖,后续所有IDep请求都返回同一个缓存实例
var dep = fixture.Freeze<IDep>();
fixture.Create<Sut>();

dep.Received(1)
   .Click(Arg.Any<int>());

方案2:手动注入自定义模拟实例

如果你不想使用Freeze,也可以自行创建模拟实例后用Inject方法注入到Fixture,效果和Freeze完全一致:

var fixture = new Fixture().Customize(
  new AutoNSubstituteCustomization { ConfigureMembers = true }
);

var dep = Substitute.For<IDep>();
fixture.Inject(dep); // 手动注入实例,Fixture后续解析IDep时都会返回该实例
fixture.Create<Sut>();

dep.Received(1)
   .Click(Arg.Any<int>());

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 00:36:04