NUnit testing framework with TestCase, SetUp/TearDown, assertions, and parameterized tests for .NET applications. USE WHEN: user mentions "NUnit", "TestCase", "TestFixture", "NUnit assertions", "NUnit parameterized tests", ".NET NUnit" DO NOT USE FOR: xUnit - use `xunit`, MSTest, JavaScript testing frameworks

GitHub
Install command
npx skhub add claude-dev-suite/nunit
Markdown
SKILL.md

NUnit - Quick Reference

Deep Knowledge: Use mcp__documentation__fetch_docs with technology: xunit for .NET testing patterns (concepts transfer).

Basic Test Structure

[TestFixture]
public class UserServiceTests
{
    private Mock<IUserRepository> _repository = null!;
    private UserService _service = null!;

    [SetUp]
    public void SetUp()
    {
        _repository = new Mock<IUserRepository>();
        _service = new UserService(_repository.Object, Mock.Of<ILogger<UserService>>());
    }

    [Test]
    public async Task GetById_ExistingUser_ReturnsUser()
    {
        _repository.Setup(r => r.GetByIdAsync(1))
            .ReturnsAsync(new User { Id = 1, Name = "Alice" });

        var result = await _service.GetByIdAsync(1);

        Assert.That(result, Is.Not.Null);
        Assert.That(result!.Name, Is.EqualTo("Alice"));
    }

    [Test]
    public async Task GetById_NonExisting_ReturnsNull()
    {
        _repository.Setup(r => r.GetByIdAsync(999)).ReturnsAsync((User?)null);

        var result = await _service.GetByIdAsync(999);

        Assert.That(result, Is.Null);
    }
}

Parameterized Tests

[TestCase("", false)]
[TestCase("a", false)]
[TestCase("ab", true)]
[TestCase("valid name", true)]
public void IsValidName_ReturnsExpected(string name, bool expected)
{
    var result = _validator.IsValidName(name);
    Assert.That(result, Is.EqualTo(expected));
}

[TestCaseSource(nameof(GetTestData))]
public void Calculate_ReturnsExpected(int a, int b, int expected)
{
    Assert.That(_calculator.Add(a, b), Is.EqualTo(expected));
}

private static IEnumerable<TestCaseData> GetTestData()
{
    yield return new TestCaseData(1, 2, 3).SetName("Positive numbers");
    yield return new TestCaseData(-1, 1, 0).SetName("Mixed signs");
    yield return new TestCaseData(0, 0, 0).SetName("Zeros");
}

Constraint-Based Assertions

// Equality
Assert.That(result, Is.EqualTo(42));
Assert.That(name, Is.EqualTo("alice").IgnoreCase);

// Comparison
Assert.That(age, Is.GreaterThan(0).And.LessThan(150));
Assert.That(price, Is.InRange(0m, 1000m));

// Collections
Assert.That(users, Has.Count.EqualTo(3));
Assert.That(users, Has.Exactly(1).Matches<User>(u => u.Name == "Alice"));
Assert.That(names, Is.Ordered.Ascending);
Assert.That(items, Does.Contain("expected"));

// Exceptions
Assert.ThrowsAsync<NotFoundException>(async () => await _service.GetByIdAsync(999));
Assert.That(async () => await _service.CreateAsync(null!), Throws.ArgumentNullException);

// String
Assert.That(message, Does.StartWith("Error").And.Contains("not found"));

SetUp and TearDown

[TestFixture]
public class IntegrationTests
{
    [OneTimeSetUp]  // Runs once before all tests
    public async Task OneTimeSetUp() { /* DB setup */ }

    [SetUp]  // Runs before each test
    public void SetUp() { /* Reset state */ }

    [TearDown]  // Runs after each test
    public void TearDown() { /* Cleanup */ }

    [OneTimeTearDown]  // Runs once after all tests
    public async Task OneTimeTearDown() { /* DB teardown */ }
}

Anti-Patterns

Anti-PatternWhy It's BadCorrect Approach
Classic Assert.AreEqualLess readableUse constraint model Assert.That
Shared state between testsFlaky testsReset in [SetUp]
[Test] on async voidExceptions lostUse async Task return type
Too many asserts per testHard to identify failureOne logical assertion per test

Quick Troubleshooting

IssueLikely CauseSolution
Test not discoveredMissing [Test] or [TestFixture]Add required attributes
SetUp not runningWrong attributeUse [SetUp] not [Setup]
Async test ignoredMissing async TaskChange return type from void
TestCaseSource failsMethod not staticMake source method static
Discovery
Tags

No tags published for this skill.

Version
Latest version metadata

Version

v2026.09.24

Published

Sep 24, 2026

Category

Uncategorized

License

MIT

Source path

skills/testing/nunit

Default branch

main

Latest commit

9496306

Tree SHA

fe4e2f1