---
title: AutoNSubstitute
description: NSubstitute integration — create substitutes automatically with AutoNSubstituteCustomization.
---

[NSubstitute](https://nsubstitute.github.io/) is a .NET mocking library with a substitute-focused API. You create substitutes for interfaces and abstract types, then configure returns and assert received calls.

**AutoFixture.AutoNSubstitute** plugs NSubstitute into AutoFixture. When AutoFixture builds an object graph and needs an interface or abstract dependency, AutoNSubstitute supplies a substitute instead of failing — so collaborators resolve automatically and you can assert on them with less manual setup.

## Prerequisites

- .NET 8+ test project
- [AutoFixture](/docs/get-started/installation) 5.0.0-rc.1
- NSubstitute

## Install

Install **AutoFixture.AutoNSubstitute** and add an explicit **NSubstitute** package reference in the same test project.

Pin **matching versions** of AutoFixture and AutoFixture.AutoNSubstitute. Reference the **latest NSubstitute** yourself when you update packages.

```xml
<PackageReference Include="AutoFixture" Version="5.0.0-rc.1" />
<PackageReference Include="AutoFixture.AutoNSubstitute" Version="5.0.0-rc.1" />
<PackageReference Include="NSubstitute" Version="5.3.0" />
```

## Example scenario

You are testing `OrderService` with an `IOrderRepository` dependency. You want NSubstitute to create the substitute and verify `Save` was called. Other tests need substitute methods to return fixture values, or NSubstitute-backed delegates.

## Basic usage

```csharp
var fixture = new Fixture().Customize(new AutoNSubstituteCustomization());
var repository = fixture.Freeze<IOrderRepository>();

var service = fixture.Create<OrderService>();
var order = fixture.Create<Order>();

service.PlaceOrder(order);

repository.Received(1).Save(order);
```

`Create<OrderService>()` injects a substitute `IOrderRepository`. `Freeze<IOrderRepository>()` keeps one substitute so you can assert with `Received`.

NSubstitute has no separate wrapper type like Moq's `Mock<T>`. Freeze or create the interface (or abstract type) directly — the specimen *is* the substitute.

Combine with [xUnit.net 3](/docs/integrations/xunit3) via a [custom AutoData attribute](/docs/integrations/xunit3#custom-autodata-attribute) when tests use `[AutoData]`.

## SubstituteAttribute

[`[Substitute]`](/api/autonsubstitute/5-0-0-rc-1/autofixture.autonsubstitute.substituteattribute) marks an AutoData parameter, property, or field so AutoFixture creates an NSubstitute substitute of that type — even when the type is a concrete class AutoFixture would otherwise construct.

Use a custom AutoData attribute that applies `AutoNSubstituteCustomization`:

```csharp
public class AutoNSubstituteDataAttribute : AutoDataAttribute
{
    public AutoNSubstituteDataAttribute()
        : base(() => new Fixture().Customize(new AutoNSubstituteCustomization()))
    {
    }
}
```

```csharp
public class Calculator
{
    public virtual int Add(int a, int b) => a + b;
}
```

```csharp
[Theory, AutoNSubstituteData]
public void SubstituteAttribute_CreatesSubstituteForConcreteParameter(
    [Substitute] Calculator calculator)
{
    calculator.Add(1, 2).Returns(42);

    Assert.Equal(42, calculator.Add(1, 2));
}
```

Without `[Substitute]`, AutoFixture builds a real `Calculator` and `.Returns` does not apply. Interfaces and abstract types already become substitutes through the residue collector, so the attribute is most useful for concrete types with virtual members.

## Configuration options

[`AutoNSubstituteCustomization`](/api/autonsubstitute/5-0-0-rc-1/autofixture.autonsubstitute.autonsubstitutecustomization) exposes properties you set before calling `Customize`. Defaults are all off / default relay:

| Property | Default | Effect |
| --- | --- | --- |
| `ConfigureMembers` | `false` | When `true`, substitute members return values from the fixture |
| `GenerateDelegates` | `false` | When `true`, NSubstitute creates delegates (`Func`, `Action`, …) |
| `Relay` | `SubstituteRelay` | Residue collector that turns interface/abstract requests into substitutes |

```csharp
var fixture = new Fixture().Customize(new AutoNSubstituteCustomization
{
    ConfigureMembers = true,
    GenerateDelegates = true
});
```

### ConfigureMembers

With the default (`ConfigureMembers = false`), NSubstitute uses its usual defaults — methods return type defaults unless you configure them:

```csharp
public interface IGreeter
{
    string Greet();
}
```

```csharp
var fixture = new Fixture().Customize(new AutoNSubstituteCustomization());

var greeter = fixture.Create<IGreeter>();

Assert.Equal(string.Empty, greeter.Greet());
```

With `ConfigureMembers = true`, AutoFixture configures substitute members so calls return specimens from the fixture:

```csharp
var fixture = new Fixture().Customize(new AutoNSubstituteCustomization
{
    ConfigureMembers = true
});
var order = fixture.Freeze<Order>();

var repository = fixture.Create<ICommerceOrderRepository>();

Assert.Same(order, repository.GetById(1));
```

Use `ConfigureMembers` when the SUT reads from collaborators and you want anonymous return values without configuring every member. Prefer the default when you only care about verifying calls (as in the basic `Received` example).

The older `AutoConfiguredNSubstituteCustomization` type is obsolete — use `new AutoNSubstituteCustomization { ConfigureMembers = true }` instead.

`ConfigureMembers` covers most virtual members, including generics. It does **not** configure:

- Methods inherited from `object` (`Equals`, `GetHashCode`, `ToString`) — NSubstitute limitation
- Members that are not overridable (sealed / non-virtual on concrete types)

Repeated calls with the same arguments return the same specimen by default. Configure those members with NSubstitute when you need different behavior.

### GenerateDelegates

By default, AutoFixture's own kernel creates delegates. With `GenerateDelegates = true`, NSubstitute creates them instead — useful when you want substitute or auto-configured delegates:

```csharp
var fixture = new Fixture().Customize(new AutoNSubstituteCustomization
{
    GenerateDelegates = true,
    ConfigureMembers = true
});
var expected = fixture.Freeze<string>();

var format = fixture.Create<Func<int, string>>();

Assert.Equal(expected, format(42));
```

Without `ConfigureMembers`, the NSubstitute delegate still exists but return values stay at NSubstitute defaults unless you configure them.

### Relay

`Relay` is the specimen builder added to `fixture.ResidueCollectors`. The default [`SubstituteRelay`](/api/autonsubstitute/5-0-0-rc-1/autofixture.autonsubstitute.substituterelay) answers requests for interfaces and abstract types with NSubstitute substitutes.

Most tests leave the default. Replace it only when you need a custom residue collector — for example a `SubstituteRelay` with a different request specification:

```csharp
var fixture = new Fixture().Customize(new AutoNSubstituteCustomization
{
    Relay = new SubstituteRelay(new ExactTypeSpecification(typeof(IOrderRepository)))
});
```

That example would substitute only `IOrderRepository` requests that match the specification you supply; other abstractions follow the rest of the fixture pipeline.

## How it works

- **`AutoNSubstituteCustomization`** — registers NSubstitute substitute creation and a residue collector for abstractions
- **`[Substitute]`** — force a substitute for an AutoData parameter/property/field
- **`ConfigureMembers`** — auto-configure substitute members from the fixture (with known gaps — see above)
- **`GenerateDelegates`** — create delegates with NSubstitute instead of the AutoFixture kernel
- **`Relay`** — residue collector (default `SubstituteRelay`) for interface/abstract requests
- **`Freeze<T>()`** — one shared substitute for setup and verification

## Next steps

- [Integrations overview](/docs/integrations)
- [AutoMoq](/docs/integrations/automoq)
- [AutoFakeItEasy](/docs/integrations/autofakeiteasy)
- [Custom AutoData attribute](/docs/integrations/xunit3#custom-autodata-attribute)
- [Register, Freeze, and Inject](/docs/how-to/register-freeze-inject)
- [FAQ](/docs/reference/faq)

## API

- [AutoFixture.AutoNSubstitute package](/api/autonsubstitute/5-0-0-rc-1)
- [`AutoNSubstituteCustomization`](/api/autonsubstitute/5-0-0-rc-1/autofixture.autonsubstitute.autonsubstitutecustomization)
- [`SubstituteRelay`](/api/autonsubstitute/5-0-0-rc-1/autofixture.autonsubstitute.substituterelay)
- [`SubstituteAttribute`](/api/autonsubstitute/5-0-0-rc-1/autofixture.autonsubstitute.substituteattribute)
