用途
本技能用于在 .NET 项目中把 AutoFixture 与 NSubstitute 整合起来,实现自动模拟(Auto-Mocking)。当需要自动创建 Mock 对象、简化依赖注入较多的测试时使用。它解决的是“每个接口都要手动写 Substitute.For<T>()”这类样板代码问题,让测试更易维护。
主要能力
- 自动为接口或抽象类建立 NSubstitute 替身,并注入到构造函数中。
- 保持同一测试内相同类型替身实例的一致性。
- 通过 [Frozen] 控制某一类型实例的冻结与复用。
- 支持 Greedy 构造策略、参数化测试与自定义 AutoData 属性。
- 可对不适合 Mock 的依赖(如 IMapper)做自定义真实实例处理。
- 当构造函数变更时,测试代码通常不需要同步修改。
使用方式
必要套件安装:
dotnet add package AutoFixture.AutoNSubstitute
相关套件(如尚未安装):
dotnet add package AutoFixture
dotnet add package AutoFixture.Xunit2
dotnet add package NSubstitute
dotnet add package xunit
建立 Fixture:
using AutoFixture;
using AutoFixture.AutoNSubstitute;
var fixture = new Fixture().Customize(new AutoNSubstituteCustomization());
var service = fixture.Create<MyService>();
Frozen 冻结机制示例:
[Theory]
[AutoData]
public async Task TestMethod(
[Frozen] IRepository repository,
MyService sut)
{
repository.GetAsync(Arg.Any<int>()).Returns(someData);
var result = await sut.DoSomething();
}
自定义 AutoData 属性示例:
public class AutoDataWithCustomizationAttribute : AutoDataAttribute
{
public AutoDataWithCustomizationAttribute() : base(CreateFixture)
{
}
private static IFixture CreateFixture()
{
var fixture = new Fixture()
.Customize(new AutoNSubstituteCustomization())
.Customize(new MapsterMapperCustomization())
.Customize(new DomainCustomization());
return fixture;
}
}
InlineAutoData 自定义属性示例:
public class InlineAutoDataWithCustomizationAttribute : InlineAutoDataAttribute
{
public InlineAutoDataWithCustomizationAttribute(params object[] values)
: base(new AutoDataWithCustomizationAttribute(), values)
{
}
}
输出格式:产生自订 AutoDataAttribute 衍生类别档案(*AutoDataAttribute.cs)、产生 ICustomization 实作类别档案(*Customization.cs),测试方法使用 [Theory] 搭配自订 AutoData 属性,[Frozen] 参数置于 SUT 参数之前,并搭配 NSubstitute 的 Returns() 与 Received() 进行行为设定与验证。
適用场景
建议使用:服务层测试(通常有多个依赖)、复杂依赖图、参数化测试、需要大量测试数据、快速迭代开发。
谨慎使用:单一依赖测试、需要精确控制属性值、团队不熟悉 AutoFixture、除错困难的场景、效能敏感的测试。
限制与注意事项
- 参数顺序错误会导致 [Frozen] 失效,必须置于 SUT 之前。
- 忘记加入 AutoNSubstituteCustomization 时,接口会自动产生异常。
- 过度依赖自动产生会让测试意图不明确。
- 每个测试方法都会建立新的 Fixture 与所有依赖,复杂对象图可能增加测试执行时间。
相关技能
autofixture-basics、autofixture-customization、autodata-xunit-integration、nsubstitute-mocking。
参考资源
原始文章:Day 13 - AutoFixture 整合 NSubstitute:自动建立 Mock 对象(https://ithelp.ithome.com.tw/articles/10375419);范例程式码:https://github.com/kevintsengtw/30Days_in_Testing_Samples/tree/main/day13。官方文件与延伸阅读详见资料。