SuperAPI AI 工具集

dotnet-testing-autofixture-nsubstitute-integration

测试与质量

查看项目

更新于 10-15 18:02

技能介绍

用途

本技能用于在 .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。官方文件与延伸阅读详见资料。