---
title: NUnit 4
description: Use AutoData, InlineAutoData, and parameter attributes with NUnit 4 test projects.
---

[NUnit](https://nunit.org/) is a long-standing .NET unit testing framework. Tests can take parameters; you normally supply those values yourself (or with `[TestCase]` / `[TestCaseSource]`).

**AutoFixture.NUnit4** connects AutoFixture to NUnit 4. Attributes such as `[AutoData]` and `[InlineAutoData]` fill test parameters with anonymous specimens so you skip most of the arrange setup. The pattern matches [xUnit.net 3](/docs/integrations/xunit3), but uses NUnit's `[Test]` attribute.

## Prerequisites

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

## Install

```xml
<PackageReference Include="AutoFixture" Version="5.0.0-rc.1" />
<PackageReference Include="AutoFixture.NUnit4" Version="5.0.0-rc.1" />
<PackageReference Include="NUnit" Version="4.3.2" />
```

Pin matching versions of **AutoFixture** and **AutoFixture.NUnit4** in the same project.

## Example scenario

You are testing `MyClass.Echo` with NUnit. The test needs an integer and a `MyClass` instance without manual arrange code. Later tests freeze collaborators, pick constructors, or share fixture setup across tests.

## AutoData

```csharp
[Test, AutoData]
public void AutoData_ProvidesTestParameters(int expectedNumber, MyClass sut)
{
    var result = sut.Echo(expectedNumber);

    Assert.That(result, Is.EqualTo(expectedNumber));
}
```

## InlineAutoData

Mix explicit values with generated ones. Explicit arguments fill parameters left-to-right; AutoFixture generates the rest. Apply one or more `[InlineAutoData]` attributes on a `[Test]` method:

```csharp
[Test]
[InlineAutoData("alpha")]
[InlineAutoData("alpha", "beta")]
public void InlineAutoData_MixesExplicitAndGeneratedValues(string first, string second)
{
    Assert.That(first, Is.EqualTo("alpha"));
    Assert.That(second, Is.Not.Null.And.Not.Empty);
}
```

## Parameter attributes

Apply attributes on test parameters to customize how that parameter (and later parameters) are created.

### Frozen

Without `[Frozen]`, each parameter of the same type gets its own anonymous instance. [`[Frozen]`](/api/nunit4/5-0-0-rc-1/autofixture.nunit4.frozenattribute) tells AutoFixture: create this parameter once, then reuse that same instance for later requests of a matching type.

```csharp
[Test, AutoData]
public void Frozen_SharesSameInstance([Frozen] string first, string second)
{
    Assert.That(second, Is.EqualTo(first));
}
```

Only parameters that come **after** the frozen one reuse it. Earlier parameters of the same type stay independent.

### Frozen with Matching

By default, freeze matches the **exact type** only (`Matching.ExactType`). A frozen `InMemoryOrderRepository` would not satisfy an `IOrderRepository` constructor parameter.

Use [`Matching`](/api/nunit4/5-0-0-rc-1/autofixture.nunit4.matching) to widen what the frozen value can satisfy:

```csharp
[Test, AutoData]
public void Frozen_ByImplementedInterfaces_InjectsConcreteIntoInterface(
    [Frozen(Matching.ImplementedInterfaces)] InMemoryOrderRepository repository,
    OrderService sut,
    Order order)
{
    sut.PlaceOrder(order);

    Assert.That(repository.Saved, Does.Contain(order));
}
```

`OrderService` needs `IOrderRepository`. With `Matching.ImplementedInterfaces`, the frozen concrete repository is also used wherever that interface is requested — so `sut` and `repository` share one instance and you can assert on `repository.Saved`.

| Flag | Matches requests for… |
| --- | --- |
| `ExactType` | The same type as the parameter (default) |
| `DirectBaseType` | The parameter's immediate base type |
| `ImplementedInterfaces` | Interfaces the parameter type implements |
| `ParameterName` | A constructor/method parameter with the same name |
| `PropertyName` | A property with the same name |
| `FieldName` | A field with the same name |
| `MemberName` | Parameter, property, or field with the same name |

Combine flags with `|`, for example `Matching.ExactType | Matching.ImplementedInterfaces`.

### Modest and Greedy

When a type has several constructors, AutoFixture must pick one. For `MultiCtorProduct` that means: parameterless, name-only, or name + price.

- **`[Modest]`** — prefer the constructor with the **fewest** parameters (most modest). Here that is the parameterless constructor, so you get the hard-coded defaults `"default"` / `0m`.
- **`[Greedy]`** — prefer the constructor with the **most** parameters (greediest). Here that is `(string name, decimal price)`, so AutoFixture generates anonymous values for both.

```csharp
[Test, AutoData]
public void ModestAttribute_UsesParameterlessConstructor([Modest] MultiCtorProduct product)
{
    Assert.That(product.Name, Is.EqualTo("default"));
    Assert.That(product.Price, Is.EqualTo(0m));
}

[Test, AutoData]
public void GreedyAttribute_UsesFullestConstructor([Greedy] MultiCtorProduct product)
{
    Assert.That(product.Name, Is.Not.Null.And.Not.Empty);
    Assert.That(product.Price, Is.Not.EqualTo(0m));
}
```

You can combine attributes on one parameter, for example `[Frozen][Greedy]`. See also [Behaviors](/docs/fundamentals/behaviors).

### NoAutoProperties

By default, after construction AutoFixture assigns anonymous values to writable public properties. [`[NoAutoProperties]`](/api/nunit4/5-0-0-rc-1/autofixture.nunit4.noautopropertiesattribute) turns that off for the parameter's type — the instance is created, but properties keep their type defaults (here `string.Empty` for `Name`).

```csharp
[Test, AutoData]
public void NoAutoProperties_LeavesWritablePropertiesUnset([NoAutoProperties] Person person)
{
    Assert.That(person.Name, Is.EqualTo(string.Empty));
}
```

### FavorArrays, FavorLists, and FavorEnumerables

Like Modest/Greedy, these change **which constructor** is chosen when a type overloads constructors that take different collection shapes:

- **`[FavorArrays]`** — prefer a constructor that takes an array (`T[]`)
- **`[FavorLists]`** — prefer a constructor that takes `IList<T>`
- **`[FavorEnumerables]`** — prefer a constructor that takes `IEnumerable<T>`

Use them when the type exposes several collection constructors and the default choice is not the one your test needs.

### Custom parameter attribute

Subclass [`CustomizeAttribute`](/api/nunit4/5-0-0-rc-1/autofixture.nunit4.customizeattribute) and return an `ICustomization` from `GetCustomization`. AutoFixture applies it when resolving that parameter:

```csharp
using System.Reflection;
using AutoFixture;
using AutoFixture.NUnit4;

public sealed class NamedAttribute(string name) : CustomizeAttribute
{
    public override ICustomization GetCustomization(ParameterInfo parameter)
    {
        ArgumentNullException.ThrowIfNull(parameter);

        return new NamedCustomization(name);
    }

    private sealed class NamedCustomization(string value) : ICustomization
    {
        public void Customize(IFixture fixture) => fixture.Inject(value);
    }
}

[Test, AutoData]
public void CustomParameterAttribute_InjectsConfiguredValue([Named("widget")] string name)
{
    Assert.That(name, Is.EqualTo("widget"));
}
```

`[Named("widget")]` injects the fixed string `"widget"` for that parameter instead of an anonymous value. Use custom attributes for team-specific rules that do not already exist as built-ins. Combine with `[Frozen]` when later parameters should reuse the same value.

## Custom AutoData attribute

When tests need the same fixture setup (for example AutoMoq), define a custom attribute instead of repeating `Customize` in every test.

Add [AutoMoq](/docs/integrations/automoq) when the factory uses `AutoMoqCustomization`.

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

[Test, AutoMoqData]
public void CustomAutoData_UsesFixtureFactory(OrderService service, Order order)
{
    Assert.That(service, Is.Not.Null);

    Assert.That(() => service.PlaceOrder(order), Throws.Nothing);
}
```

Subclass `AutoDataAttribute` and pass a factory `Func<IFixture>` to the base constructor. The factory runs once per test case and supplies the configured fixture; parameters are resolved from that fixture.

## Custom InlineAutoData attribute

Subclass [`InlineAutoDataAttribute`](/api/nunit4/5-0-0-rc-1/autofixture.nunit4.inlineautodataattribute) the same way — pass a fixture factory plus the inline values:

```csharp
public class InlineAutoMoqDataAttribute : InlineAutoDataAttribute
{
    public InlineAutoMoqDataAttribute(params object[] values)
        : base(() => new Fixture().Customize(new AutoMoqCustomization()), values)
    {
    }
}

[Test]
[InlineAutoMoqData(42)]
public void CustomInlineAutoData_MixesExplicitValuesWithCustomFixture(
    int orderId,
    OrderService service,
    string productName)
{
    Assert.That(orderId, Is.EqualTo(42));
    Assert.That(service, Is.Not.Null);
    Assert.That(productName, Is.Not.Null.And.Not.Empty);

    Assert.That(() => service.PlaceOrder(new Order(orderId, productName)), Throws.Nothing);
}
```

Explicit values still fill parameters left-to-right; AutoFixture fills the rest from the customized fixture.

## How it works

- **`[AutoData]`** — NUnit `[Test]` methods get anonymous parameters from AutoFixture
- **`[InlineAutoData(...)]`** — explicit inline values fill parameters left-to-right; AutoFixture generates the rest
- **`[Frozen]` / `[Frozen(Matching...)]`** — create once; reuse for later matching requests (exact type, interfaces, names, …)
- **`[Modest]` / `[Greedy]`** — fewest vs most constructor parameters
- **`[NoAutoProperties]`** — construct without filling writable properties
- **`[FavorArrays]` / `[FavorLists]` / `[FavorEnumerables]`** — prefer constructors that take that collection shape
- **Custom `CustomizeAttribute`** — return an `ICustomization` for that parameter
- Subclass `AutoDataAttribute` or `InlineAutoDataAttribute` to share fixture setup across tests

Migrating from NUnit 3? See [Previous versions](/docs/reference/previous-versions).

## Next steps

- [Integrations overview](/docs/integrations)
- [AutoMoq](/docs/integrations/automoq)
- [Behaviors](/docs/fundamentals/behaviors)
- [Register, Freeze, and Inject](/docs/how-to/register-freeze-inject)
- [xUnit.net 3](/docs/integrations/xunit3)
- [Previous versions](/docs/reference/previous-versions)
- [FAQ](/docs/reference/faq)

## API

- [AutoFixture.NUnit4 package](/api/nunit4/5-0-0-rc-1)
- [`AutoDataAttribute`](/api/nunit4/5-0-0-rc-1/autofixture.nunit4.autodataattribute)
- [`InlineAutoDataAttribute`](/api/nunit4/5-0-0-rc-1/autofixture.nunit4.inlineautodataattribute)
- [`FrozenAttribute`](/api/nunit4/5-0-0-rc-1/autofixture.nunit4.frozenattribute)
- [`Matching`](/api/nunit4/5-0-0-rc-1/autofixture.nunit4.matching)
- [`ModestAttribute`](/api/nunit4/5-0-0-rc-1/autofixture.nunit4.modestattribute)
- [`GreedyAttribute`](/api/nunit4/5-0-0-rc-1/autofixture.nunit4.greedyattribute)
- [`NoAutoPropertiesAttribute`](/api/nunit4/5-0-0-rc-1/autofixture.nunit4.noautopropertiesattribute)
- [`FavorArraysAttribute`](/api/nunit4/5-0-0-rc-1/autofixture.nunit4.favorarraysattribute)
- [`FavorListsAttribute`](/api/nunit4/5-0-0-rc-1/autofixture.nunit4.favorlistsattribute)
- [`FavorEnumerablesAttribute`](/api/nunit4/5-0-0-rc-1/autofixture.nunit4.favorenumerablesattribute)
- [`CustomizeAttribute`](/api/nunit4/5-0-0-rc-1/autofixture.nunit4.customizeattribute)
