| name | dotnet-testing-autofixture-nsubstitute-integration |
| category | testing |
| subcategory | mocking |
| description | AutoFixture and NSubstitute Integration Guide - Implementing Auto-Mocking. Use when you need to automatically create mock objects and simplify testing of complex dependency injection. Covers AutoNSubstituteDataAttribute, Frozen mechanism, Greedy construction strategy. Includes customized handling for special dependencies like IMapper (AutoMapper/Mapster).
Keywords: autofixture nsubstitute, auto mocking, AutoNSubstituteDataAttribute, auto-mocking, Frozen, AutoNSubstituteCustomization, AutoFixture.AutoNSubstitute, Greedy, fixture.Freeze, Received(), Returns(), IMapper, AutoMapper, Mapster, mapper testing
|
| targets | ["*"] |
| license | MIT |
| metadata | {"author":"Kevin Tseng","version":"1.0.0","tags":"autofixture, nsubstitute, auto-mocking, dependency-injection, xunit, testing","related_skills":"nsubstitute-mocking, autofixture-basics, autodata-xunit-integration"} |
| claudecode | {} |
| opencode | {} |
| codexcli | {"short-description":".NET skill guidance for dotnet-testing-autofixture-nsubstitute-integration"} |
| copilot | {} |
| geminicli | {} |
| antigravity | {} |
Source: kevintsengtw/dotnet-testing-agent-skills (MIT). Ported into dotnet-agent-harness.
AutoFixture + NSubstitute Auto-Mocking Integration
Applicable Scenarios
This skill introduces how to integrate AutoFixture with NSubstitute through the AutoFixture.AutoNSubstitute package to
implement auto-mocking functionality. This integration approach significantly simplifies testing of service classes with
multiple dependencies, allowing developers to focus on test logic rather than tedious object creation.
When to Use
Use this skill when asked to perform the following tasks:
- Test service classes with multiple interface dependencies
- Create test setups that automatically mock all interface dependencies
- Use
[Frozen] attribute to ensure dependency instances remain consistent throughout tests
- Create project-level custom AutoData attributes to integrate multiple customization settings
- Combine fixed test values with automatically generated objects for parameterized tests
Core Value
- Reduce boilerplate code: No need to manually create
Substitute.For<T>() for each interface
- Automatically handle complex dependency graphs: AutoFixture automatically resolves and creates required objects
- Improve test maintainability: When constructors change, test code usually doesn't need to be modified
- Maintain test focus: Let developers focus on test logic rather than object creation
Package Installation and Configuration
Required Packages
dotnet add package AutoFixture.AutoNSubstitute
dotnet add package AutoFixture
dotnet add package AutoFixture.Xunit2
dotnet add package NSubstitute
dotnet add package xunit
```text
| Package Name | Purpose | NuGet Link |
| ----------------------------- | ------------------------------------- | ------------------------------------------------------------------------ |
| `AutoFixture.AutoNSubstitute` | AutoFixture and NSubstitute Integration | [nuget.org](https://www.nuget.org/packages/AutoFixture.AutoNSubstitute/) |
| `AutoFixture.Xunit2` | xUnit Integration (AutoData attributes) | [nuget.org](https://www.nuget.org/packages/AutoFixture.Xunit2/) |
| `NSubstitute` | Mocking Framework | [nuget.org](https://www.nuget.org/packages/NSubstitute/) |
---
When adding `AutoNSubstituteCustomization` to AutoFixture, it automatically:
1. **Detects interface types**: When AutoFixture encounters interfaces or abstract classes
2. **Automatically creates substitutes**: Uses NSubstitutet need modification
---
In actual projects, you typically need to integrate multiple customization settings:
- **AutoNSubstituteCustomization**: Automatically creates NSubstitute substitutes interfaces
- **Project-specific Customizations**: Such as Mapper settings, validator settings, etc.
- **Consistent infrastructure**: Ensures the entire project uses the same settings
```csharp
using AutoFixture;
using AutoFixture.AutoNSubstitute;
using AutoFixture.Xunit2;
namespace MyProject.Tests.AutoFixtureConfigurations;
/// <summary>
/// AutoData attribute with custom customization settings
/// </summary>
public class AutoDataWithCustomizationAttribute : AutoDataAttribute
{
/// <summary>
/// Constructor
/// </summary>
public AutoDataWithCustomizationAttribute() : base(CreateFixture)
{
}
private static IFixture ()
{
var fixture = new Fixture()
.Customize(new AutoNSubstituteCustomization())
.Customize(new MapsterMapperCustomization()) // Project-specific settings
.Customize(new DomainCustomization()); // Domain model settings
fixture;
}
}
```text
For combining fixed values with automatically generated objects:
```csharp
using AutoFixture;
using AutoFixture.AutoNSubstitute;
using AutoFixture.Xunit2;
namespace MyProject.Tests.AutoFixtureConfigurations;
/// <summary>
/// InlineAutoData attribute with custom customization settings
/// </summary>
public class InlineAutoDataWithCustomizationAttribute : InlineAutoDataAttribute
{
/// <summary>
/// Constructor
/// </summary>
/// <param name=>Fixed values (will fill first few parameters of method)</param>
public InlineAutoDataWithCustomizationAttribute(params object[] values)
: base(new AutoDataWithCustomizationAttribute(), values)
{
}
}
```text
```csharp
// ❌ Wrong: InlineAutoDataAttribute needs AutoDataAttribute, not Func<IFixture>
public InlineAutoDataWithCustomizationAttribute(params object[] values)
: base(CreateFixture, values) // Compile error or unexpected behavior
// ✅ Correct: Pass AutoDataAttribute instance
public InlineAutoDataWithCustomizationAttribute(params object[] values)
: base(new AutoDataWithCustomizationAttribute(), values)
```text
Reason:
- `InlineAutoDataAttribute` inherits from `CompositeDataAttribute`
- It needs to receive an `AutoDataAttribute` instance as the data provider
- This allows reusing all settings from `AutoDataWithCustomizationAttribute`
---
Certain dependencies (like IMapper) are not suitable Mock and should use real instances. Includes customization examples Mapster and AutoMapper.
> For complete customization examples, see [references/dependency-customization.md](references/dependency-customization.md)
---
Covers basic tests, Frozen dependency behavior setup, automatically generated data, InlineAutoData parameterized tests, CollectionSize control, IFixture complex data setup, Nullable reference handling, and other complete examples.
> For complete implementation examples, see [references/test-implementation-examples.md](references/test-implementation-examples.md)
---
| Scenario | Reason |
| --------------------- | ----------------------------------------- |
| Service Layer Testing | Usually has multiple dependencies, maximum benefit from auto-mocking |
| Complex Dependency Graph | AutoFixture automatically handles multi-layer dependencies |
| Parameterized Testing | Combine fixed values with automatically generated data |
| Need Large Test Data | Reduce manual data creation work |
| Rapid Iteration Development | Tests usually dont take effect
public void Test(MyService sut, [Frozen] IRepository repo)
// ✅ Frozen parameter must be before SUT
public void Test([Frozen] IRepository repo, MyService sut)
```text
2. **Forgetting AutoNSubstituteCustomization**
```csharp
// ❌ Without AutoNSubstitute, interfaces will produce exceptions
var fixture = new Fixture();
// ✅ Add AutoNSubstituteCustomization
var fixture = new Fixture().Customize(new AutoNSubstituteCustomization());
```text
3. **Over-reliance on Auto-Generation**
```csharp
// ❌ Test intent unclear
public void Test(Order order, Customer customer, MyService sut)
{
var result = sut.Process(order);
result.Should().NotBeNull(); // Validating what?
}
// ✅ Explicitly control key properties
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);
}
```text
- Each method creates a new Fixture and all dependencies
- Complex object graphs may increase execution
- Consider using `[ClassData]` or `IClassFixture<T>` to share setup
---
| Skill Name | Relationship Description |
| ---------------------------- | ------------------------------------------------------ |
| `autofixture-basics` | AutoFixture basics, prerequisite knowledge this skill |
| `autofixture-customization` | Advanced usage of custom Customizations |
| `autodata-xunit-integration` | Complete explanation of AutoData attribute family |
| `nsubstitute-mocking` | NSubstitute basics, detailed Mock setup explanation |
---
This skill content is distilled from the article series:
- **Day 13 - AutoFixture Integration with NSubstitute: Automatically Creating Mock Objects**
- Article: https://ithelp.ithome.com.tw/articles/10375419
- Sample Code: https://github.com/kevintsengtw/30Days_in_Testing_Samples/tree/main/day13
- [AutoFixture.AutoNSubstitute NuGet Package](https://www.nuget.org/packages/AutoFixture.AutoNSubstitute/)
- [AutoFixture Documentation - Auto Mocking](https://autofixture.readthedocs.io/en/stable/)
- [NSubstitute Documentation](https://nsubstitute.github.io/help/getting-started/)
- [Using AutoFixture.AutoData to Rewrite Previous Test Code | mrkt