Autofixture.NSubstitute未冻结依赖无法校验调用记录如何处理?
问题原因
AutoFixture 默认行为下,每次请求同类型实例、或者解析构造函数依赖时,都会生成一个全新的实例。Freeze<T>()的核心作用是将首次生成的T实例缓存,后续所有对T类型的请求都会返回这个唯一的缓存实例。
你当前代码的执行逻辑存在实例不匹配的问题:
- 调用
fixture.Create<Sut>()创建被测系统时,AutoFixture自动生成了第一个IDep模拟实例注入到Sut构造函数,这个实例的Click方法确实被调用了 - 后续执行
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
相关产品推荐
相关产品推荐

