Skip to main content

TUnit.Mocks

TUnit.Mocks is a standalone, source-generated, AOT-compatible mocking framework. Because mocks are generated at compile time, it works with Native AOT, trimming, and single-file publishing — unlike traditional mocking libraries that rely on runtime proxy generation.

While it integrates seamlessly with TUnit's assertion engine, TUnit.Mocks has no dependency on the TUnit test framework and works with any test runner — xUnit, NUnit, MSTest, or no framework at all.

Beta

TUnit.Mocks is currently in beta. The API may change before the stable release.

Installation

Add the NuGet package to your test project:

dotnet add package TUnit.Mocks --prerelease

For HTTP mocking or logging helpers, also add:

dotnet add package TUnit.Mocks.Http --prerelease
dotnet add package TUnit.Mocks.Logging --prerelease
C# 14 Required

TUnit.Mocks requires C# 14 or later (LangVersion set to 14 or preview). If your project targets an older version, you will see error TM004 at compile time.

Your First Mock

using TUnit.Mocks;

public interface IGreeter
{
string Greet(string name);
}

public class GreeterTests
{
[Test]
public async Task Greet_Returns_Configured_Value()
{
// Arrange — create a mock
var mock = Mock.Of<IGreeter>();

// Configure — set up a return value
mock.Greet(Any()).Returns("Hello!");

// Act — use the mock object
IGreeter greeter = mock.Object;
var result = greeter.Greet("Alice");

// Assert — verify the result and the call
await Assert.That(result).IsEqualTo("Hello!");
mock.Greet("Alice").WasCalled(Times.Once);
}
}

Key Concepts

Creating Mocks

Factory MethodUse Case
Mock.Of<T>()Mock an interface or abstract class
Mock.OfPartial<T>(args)Mock a concrete class (calls base for unconfigured methods)
Mock.OfDelegate<T>()Mock a delegate (Func<>, Action<>, etc.)
Mock.Wrap<T>(instance)Wrap a real object with selective overrides
Mock.Of<T1, T2>()Mock multiple interfaces on a single object
Mock.HttpHandler()Create a MockHttpHandler (requires TUnit.Mocks.Http)
Mock.HttpClient(baseAddress?)Create a MockHttpClient — an HttpClient with a .Handler property (requires TUnit.Mocks.Http)
Mock.Logger()Create a MockLogger (requires TUnit.Mocks.Logging)
Mock.Logger<T>()Create a MockLogger<T> implementing ILogger<T> (requires TUnit.Mocks.Logging)

All factory methods accept an optional MockBehavior parameter:

var loose = Mock.Of<IService>();                       // loose (default)
var strict = Mock.Of<IService>(MockBehavior.Strict); // throws on unconfigured calls

The Mock Wrapper

Mock.Of<T>() returns a Mock<T> wrapper. Extension methods are generated directly on Mock<T> for each member of the mocked type, and the chain methods (.Returns(), .WasCalled(), etc.) disambiguate between setup and verification:

var mock = Mock.Of<IService>();

mock.GetUser(Any()).Returns(user); // setup — .Returns() makes it a stub
mock.GetUser(42).WasCalled(Times.Once); // verify — .WasCalled() makes it a check
mock.RaiseOnMessage("hi"); // raise events — Raise{EventName}()
mock.Object // the T instance to pass to your code under test

Implicit Conversion

You can pass Mock<T> directly where T is expected — no .Object needed:

var mock = Mock.Of<IGreeter>();
IGreeter greeter = mock; // implicit conversion

Loose vs Strict Mode

ModeUnconfigured methodsDefault
MockBehavior.LooseReturn smart defaults (0, "", false, null, auto-mocked interfaces)Yes
MockBehavior.StrictThrow MockStrictBehaviorExceptionNo

Concise Argument Matching

TUnit.Mocks imports matchers globally — no Arg. prefix needed. Raw values, inline lambdas, and Any() work directly as arguments:

var mock = Mock.Of<IUserService>();

// Any() — matches everything
mock.GetUser(Any()).Returns(user);

// Raw values — implicit exact matching
mock.GetUser(42).Returns(alice);

// Inline lambdas — predicate matching directly in the call
mock.GetUser(id => id > 0).Returns(validUser);
mock.GetByRole(role => role == "admin").Returns(admins);

// Mix lambdas with Any() or raw values
mock.Search(name => name.StartsWith("A"), Any()).Returns(results);

// Is<T>() — explicit predicate matching (also works)
mock.GetUser(Is<int>(id => id > 0)).Returns(validUser);

See Argument Matchers for the full API.

What's Next

  • Setup & Stubbing — configure return values, callbacks, exceptions, and property behaviors
  • Verification — verify calls, ordering, and assertion integration
  • Argument Matchers — match arguments with predicates, patterns, and capture values
  • Advanced Features — state machines, events, auto-mocking, diagnostics, and more
  • HTTP Mocking — mock HttpClient with MockHttpHandler
  • Logging — capture and verify ILogger calls with MockLogger