Token导航 LogoToken导航TokenDH.com
待分类需要联网github未标认证来源可访问clear审计通过

dotnet-testing-autofixture-nsubstitute-integrationdotnet 测试自动夹具 nsubstitute 集成

Agent Skill

用于辅助测试设计、自动化测试、用例整理和回归验证。它适合让 Agent 编写单元测试、端到端测试、测试计划或根据失败日志定位问题。使用时需要确认项目测试框架、运行命令和夹具数据,避免为了通过测试而改坏真实逻辑;涉及浏览器或外部服务时,应区分本地模拟、测试环境和生产环境。

总安装

558

周安装

23

GitHub Stars

24

下载量

182
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

3

许可证

MIT

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:dotnet-testing-autofixture-nsubstitute-integration(dotnet 测试自动夹具 nsubstitute 集成)
来源仓库:https://github.com/kevintsengtw/dotnet-testing-agent-skills
仓库路径:skills/dotnet-testing-autofixture-nsubstitute-integration
安装命令:
npx skills add https://github.com/kevintsengtw/dotnet-testing-agent-skills --skill dotnet-testing-autofixture-nsubstitute-integration
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/kevintsengtw/dotnet-testing-agent-skills --skill dotnet-testing-autofixture-nsubstitute-integration

简介

dotnet-testing-autofixture-nsubstitute-integration 自动为接口创建 NSubstitute 模拟对象。

  • 消除手动 Substitute.For<T>() 样板代码,自动解析依赖图构建替身链。
  • 当构造函数变更时测试代码通常无需同步修改,提升可维护性。
  • 需安装 AutoFixture.AutoNSubstitute 桥接包并启用自定义配置。
  • 注意模拟对象返回值需在测试中显式设定,否则返回默认空值。

SKILL.md

AutoFixture + NSubstitute 自動模擬整合

核心價值

  • 減少樣板程式碼:不需要手動為每個介面建立 Substitute.For<T>()
  • 自動處理複雜相依圖:AutoFixture 會自動解析並建立所需的物件
  • 提升測試維護性:當建構函式變更時,測試程式碼通常不需要同步修改
  • 保持測試重點:讓開發者專注於測試邏輯而非物件建立

套件安裝與設定

必要套件

# 核心套件
dotnet add package AutoFixture.AutoNSubstitute

# 相關套件(如尚未安裝)
dotnet add package AutoFixture
dotnet add package AutoFixture.Xunit2
dotnet add package NSubstitute
dotnet add package xunit

NuGet 套件資訊

套件名稱用途NuGet 連結
AutoFixture.AutoNSubstituteAutoFixture 與 NSubstitute 整合nuget.org
AutoFixture.Xunit2xUnit 整合(AutoData 屬性)nuget.org
NSubstitute模擬框架nuget.org

核心概念

AutoNSubstituteCustomization 的作用

當在 AutoFixture 中加入 AutoNSubstituteCustomization 時,它會自動:

  1. 偵測介面類型:當 AutoFixture 遇到介面或抽象類別時
  2. 自動建立替身:使用 NSubstitute 的 Substitute.For<T>() 建立 Mock 物件
  3. 注入相依性:將這些替身物件注入到需要的建構函式中
  4. 保持實例一致性:確保相同類型的替身在同一個測試中保持一致
using AutoFixture;
using AutoFixture.AutoNSubstitute;

// 建立包含 AutoNSubstitute 功能的 Fixture
var fixture = new Fixture().Customize(new AutoNSubstituteCustomization());

// 自動建立服務和其相依性
// MyService 的所有介面相依性都會自動變成 NSubstitute 的替身
var service = fixture.Create<MyService>();

FrozenAttribute 凍結機制

[Frozen] 屬性用來控制測試中某個類型的實例:

  • 當參數被標註為 [Frozen] 時,AutoFixture 會建立這個類別的一個實例並凍結
  • 後續在測試方法中都會使用同一個已凍結的實例
  • 這對於需要設定相依性行為然後驗證 SUT 的測試特別重要
[Theory]
[AutoData]
public async Task TestMethod(
    [Frozen] IRepository repository,  // 這個 repository 會被凍結
    MyService sut)                    // sut 會使用同一個 repository
{
    // 設定凍結實例的行為
    repository.GetAsync(Arg.Any<int>()).Returns(someData);

    // SUT 內部使用的是同一個 repository 實例
    var result = await sut.DoSomething();
}

參數順序的重要性

使用 [Frozen] 時,參數順序非常重要

// 正確:Frozen 參數在 SUT 之前
public async Task TestMethod(
    [Frozen] IRepository repository,
    MyService sut)

// 錯誤:SUT 會使用不同的 repository 實例
public async Task TestMethod(
    MyService sut,
    [Frozen] IRepository repository)  // 太晚凍結了

傳統方式 vs AutoNSubstitute 方式

傳統手動方式

[Fact]
public async Task TraditionalWay()
{
    // Arrange - 手動建立每個相依性
    var repository = Substitute.For<IRepository>();
    var logger = Substitute.For<ILogger<OrderService>>();
    var notificationService = Substitute.For<INotificationService>();
    var cacheService = Substitute.For<ICacheService>();

    var sut = new OrderService(repository, logger, notificationService, cacheService);

    // 設定替身行為
    repository.GetOrderAsync(Arg.Any<int>()).Returns(someOrder);

    // Act
    var result = await sut.GetOrderAsync(orderId);

    // Assert
    result.Should().NotBeNull();
}

問題

  • 當服務增加新相依性時,所有測試都需要修改
  • 大量重複的 Substitute.For<T>() 呼叫
  • 測試程式碼冗長,難以快速理解測試意圖

使用 AutoNSubstitute 方式

[Theory]
[AutoDataWithCustomization]
public async Task WithAutoNSubstitute(
    [Frozen] IRepository repository,
    OrderService sut)
{
    // Arrange - 相依性已自動建立,只需設定需要的行為
    repository.GetOrderAsync(Arg.Any<int>()).Returns(someOrder);

    // Act
    var result = await sut.GetOrderAsync(orderId);

    // Assert
    result.Should().NotBeNull();
}

優勢

  • 只需宣告需要互動的相依性
  • 其他相依性(logger, notificationService, cacheService)自動建立
  • 建構函式變更時,測試通常不需要修改

自訂 AutoData 屬性

為什麼需要自訂 AutoData 屬性?

在實際專案中,通常需要整合多種客製化設定:

  • AutoNSubstituteCustomization:自動為介面建立 NSubstitute 替身
  • 專案特定的 Customization:如 Mapper 設定、驗證器設定等
  • 一致的測試基礎設施:確保整個專案使用相同的設定

AutoDataWithCustomizationAttribute 實作

using AutoFixture;
using AutoFixture.AutoNSubstitute;
using AutoFixture.Xunit2;

namespace MyProject.Tests.AutoFixtureConfigurations;

/// <summary>
/// 包含客製化設定的 AutoData 屬性
/// </summary>
public class AutoDataWithCustomizationAttribute : AutoDataAttribute
{
    /// <summary>
    /// 建構函式
    /// </summary>
    public AutoDataWithCustomizationAttribute() : base(CreateFixture)
    {
    }

    private static IFixture CreateFixture()
    {
        var fixture = new Fixture()
            .Customize(new AutoNSubstituteCustomization())
            .Customize(new MapsterMapperCustomization())  // 專案特定設定
            .Customize(new DomainCustomization());        // 領域模型設定

        return fixture;
    }
}

InlineAutoDataWithCustomizationAttribute 實作

用於結合固定測試值與自動產生物件:

using AutoFixture;
using AutoFixture.AutoNSubstitute;
using AutoFixture.Xunit2;

namespace MyProject.Tests.AutoFixtureConfigurations;

/// <summary>
/// 包含客製化設定的 InlineAutoData 屬性
/// </summary>
public class InlineAutoDataWithCustomizationAttribute : InlineAutoDataAttribute
{
    /// <summary>
    /// 建構函式
    /// </summary>
    /// <param name="values">固定值(將填入測試方法的前幾個參數)</param>
    public InlineAutoDataWithCustomizationAttribute(params object[] values)
        : base(new AutoDataWithCustomizationAttribute(), values)
    {
    }
}

重要實作細節

為什麼使用 new AutoDataWithCustomizationAttribute() 而不是 CreateFixture 方法?

// 錯誤:InlineAutoDataAttribute 需要 AutoDataAttribute,不是 Func<IFixture>
public InlineAutoDataWithCustomizationAttribute(params object[] values)
    : base(CreateFixture, values)  // 編譯錯誤或行為異常

// 正確:傳遞 AutoDataAttribute 實例
public InlineAutoDataWithCustomizationAttribute(params object[] values)
    : base(new AutoDataWithCustomizationAttribute(), values)

原因:

  • InlineAutoDataAttribute 繼承自 CompositeDataAttribute
  • 它需要接收一個 AutoDataAttribute 實例作為資料來源提供者
  • 這樣可以重用 AutoDataWithCustomizationAttribute 的所有設定

常見相依性的客製化處理

某些相依性(如 IMapper)不適合使用 Mock,而應該使用真實實例。包含 Mapster 和 AutoMapper 的客製化範例。

完整客製化處理範例請參考 references/dependency-customization.md

測試實作範例

涵蓋基本測試、Frozen 相依行為設定、自動產生測試資料、InlineAutoData 參數化測試、CollectionSize 控制、IFixture 複雜資料設定、Nullable 參考類型處理等完整範例。

完整測試實作範例請參考 references/test-implementation-examples.md

適用場景判斷

建議使用的場景

場景原因
服務層測試通常有多個相依性,自動模擬效益最大
複雜相依圖AutoFixture 自動處理多層相依性
參數化測試結合固定值與自動產生資料
需要大量測試資料減少手動建立測試資料的工作
快速迭代開發建構函式變更時測試通常不需修改

謹慎使用的場景

場景原因
單一相依性測試手動建立可能更清晰直覺
精確控制屬性值需要額外的 fixture.Build().With() 設定
團隊不熟悉 AutoFixture學習成本可能影響開發效率
除錯困難的場景自動產生的物件可能讓除錯變複雜
效能敏感的測試物件建立的開銷可能影響執行速度

最佳實踐

導入策略

  1. 漸進式採用

- 從簡單的服務類別開始 - 逐步擴展到複雜場景 - 讓團隊逐漸熟悉模式

  1. 團隊培訓

- 確保團隊理解 Frozen 機制 - 說明參數順序的重要性 - 分享除錯技巧

  1. 建立規範

- 何時使用自動產生 vs 手動建立 - 自訂 Customization 的命名與組織 - 測試資料的控制策略

程式碼組織

MyProject.Tests/
├── AutoFixtureConfigurations/
│   ├── AutoDataWithCustomizationAttribute.cs
│   ├── InlineAutoDataWithCustomizationAttribute.cs
│   ├── AutoMapperCustomization.cs
│   └── DomainCustomization.cs
├── Services/
│   ├── OrderServiceTests.cs
│   └── ShipperServiceTests.cs
└── ...

命名慣例

  • 自訂 AutoData 屬性[專案名稱]AutoDataAttributeAutoDataWithCustomizationAttribute
  • Customization 類別[功能]Customization(如 MapsterMapperCustomization
  • 測試方法:維持 方法_情境_預期 的命名模式

注意事項與限制

常見陷阱

  1. 參數順序錯誤 // Frozen 參數在 SUT 之後,不會生效 public void Test(MyService sut, [Frozen] IRepository repo) // Frozen 參數必須在 SUT 之前 public void Test([Frozen] IRepository repo, MyService sut)
  2. 遺忘 AutoNSubstituteCustomization // 沒有 AutoNSubstitute,介面會產生異常 var fixture = new Fixture(); // 加入 AutoNSubstituteCustomization var fixture = new Fixture().Customize(new AutoNSubstituteCustomization());
  3. 過度依賴自動產生 // 測試意圖不明確 public void Test(Order order, Customer customer, MyService sut) {var result = sut.Process(order); result.Should().NotBeNull(); // 驗證什麼?} // 明確控制關鍵屬性 public void Test(IFixture fixture, MyService sut) {var order = fixture.Build<Order>().With(o => o.Status, OrderStatus.Pending).Create(); var result = sut.Process(order); result.Status.Should().Be(OrderStatus.Processed);}

效能考量

  • 每個測試方法都會建立新的 Fixture 和所有相依性
  • 複雜物件圖可能增加測試執行時間
  • 考慮使用 [ClassData]IClassFixture<T> 共享設定

相關技能

技能名稱關聯說明
autofixture-basicsAutoFixture 基礎使用,本技能的前置知識
autofixture-customization自訂 Customization 的進階用法
autodata-xunit-integrationAutoData 屬性家族的完整說明
nsubstitute-mockingNSubstitute 基礎,Mock 設定的詳細說明

輸出格式

  • 產生自訂 AutoDataAttribute 衍生類別檔案(*AutoDataAttribute.cs
  • 產生 ICustomization 實作類別檔案(*Customization.cs
  • 測試方法使用 [Theory] 搭配自訂 AutoData 屬性
  • [Frozen] 參數置於 SUT 參數之前
  • 搭配 NSubstitute 的 Returns()Received() 進行行為設定與驗證

參考資源

原始文章

本技能內容提煉自「老派軟體工程師的測試修練 - 30 天挑戰」系列文章:

  • Day 13 - AutoFixture 整合 NSubstitute:自動建立 Mock 對象

- 鐵人賽文章:https://ithelp.ithome.com.tw/articles/10375419 - 範例程式碼:https://github.com/kevintsengtw/30Days_in_Testing_Samples/tree/main/day13

官方文件

延伸閱讀

範例程式碼

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

04

需要参考平台分布和安装热度时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

补充不同宿主或平台的使用分布数据

能力 5

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Claude Code

27.88%
按下载量换算51

Gemini CLI

23.94%
按下载量换算44

Antigravity

17.63%
按下载量换算32

OpenCode

12.88%
按下载量换算23

windsurf

8.35%
按下载量换算15

github-copilot

4.11%
按下载量换算7

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。

来源信息

继续浏览同类 Skills