NimbleMock: A Modern, Blazing-Fast Mocking Library for .NET (34x Faster Than Moq)
Source: Dev.to

Why I Built NimbleMock
Over the years, I’ve dealt with common mocking frustrations in enterprise .NET apps:
- Verbose setups for large interfaces (mocking 20+ methods just to test one).
- Performance hits from runtime proxies (Castle.DynamicProxy in Moq) — slow creation and verification in big test suites.
- Static/sealed mocking hell — no native support without paid tools or wrappers.
- Async and generics issues — unexpected null tasks or clunky type inference.
- Brittle tests — mocks that pass locally but fail in production because they don’t match real API shapes.
Moq is battle‑tested, NSubstitute is clean and readable, but neither fully leverages modern .NET features like source generators for zero overhead.
NimbleMock fixes these with compile‑time magic: no runtime proxies, aggressive inlining, and stack allocation. Result? 34× faster mock creation and 3× faster verification than Moq, with zero allocations in typical scenarios.
Key Features
- Partial mocks – only mock what you need; unmocked methods throw
NotImplementedExceptionfor early detection. - Native static/sealed mocking – mock
DateTime.Now,Environment, etc., directly. - First‑class async support – seamless for
TaskandValueTask. - Generic type inference – full support for nested generics (e.g., EF Core
IQueryable). - Fluent, chainable API – inspired by the best of NSubstitute and Moq.
- Lie‑proofing – optional runtime validation against real staging APIs to catch outdated mock shapes.
- Compile‑time analyzers – catch errors early (e.g., warn if you forget
SetupAsyncfor async methods).
MIT‑licensed, open‑source, and ready for contributions!
Quick Start
Install via NuGet
dotnet add package NimbleMock
Basic example
using NimbleMock;
public interface IUserRepository
{
User GetById(int id);
Task SaveAsync(User user);
}
var mock = Mock.Of()
.Setup(x => x.GetById(1), new User { Id = 1, Name = "Alice" })
.SetupAsync(x => x.SaveAsync(default!), true)
.Build();
var user = mock.Object.GetById(1); // Returns Alice
mock.Verify(x => x.GetById(1)).Once();
Partial mock (perfect for god‑interfaces)
var mock = Mock.Partial()
.Only(x => x.GetData(1), expectedData)
.Build();
// Unmocked methods throw for safety
Static mocking
var staticMock = Mock.Static()
.Returns(d => d.Now, new DateTime(2025, 12, 25))
.Build();
staticMock.Verify(d => d.Now).Once();
Generics example
public interface IRepository
{
IQueryable Query();
}
var mock = Mock.Of]
.Setup(x => x.Query(), users.AsQueryable())
.Build();
var results = mock.Object.Query().Where(u => u.IsActive).ToList();
Performance Benchmarks
Run on .NET 8 (BenchmarkDotNet).
Mock Creation & Setup
| Library | Time (ns) | Memory Allocated | Gain vs Moq |
|---|---|---|---|
| Moq | 48,812 | 10.37 KB | Baseline |
| NSubstitute | 9,937 | 12.36 KB | ~5× faster |
| NimbleMock | 1,415 | 3.45 KB | 34× faster |
Method Execution Overhead
| Library | Time (µs) | Gain vs Moq |
|---|---|---|
| Moq | ~1.4 | Baseline |
| NSubstitute | ~1.6 | Slower |
| NimbleMock | ~0.6 | 2.3× faster |
Verification
| Library | Time (ns) | Memory Allocated | Gain vs Moq |
|---|---|---|---|
| Moq | 1,795 | 2.12 KB | Baseline |
| NSubstitute | 2,163 | 2.82 KB | Slower |
| NimbleMock | 585 | 0.53 KB | 3× faster |
Powered by source generators — no runtime reflection!
Run the benchmarks yourself:
dotnet run --project tests/NimbleMock.Benchmarks --configuration Release
Migrating from Moq/NSubstitute
From Moq
// Moq
var mock = new Mock<IUserRepository>();
mock.Setup(x => x.GetById(1)).Returns(user);
// NimbleMock
var mock = Mock.Of()
.Setup(x => x.GetById(1), user)
.Build();
Verification is also more readable with the fluent API. See the full migration guide in the repository.
Lie‑Proofing: Avoid “Tests That Lie”
Unique feature: validate mocks against real endpoints.
var result = await LieProofing.AssertMatchesReal("https://api.staging.example.com");
if (!result.IsValid)
{
// Log mismatches
}
Catches drifting APIs before production outages.
Final Thoughts
NimbleMock is built for .NET 8/9+ era: fast, safe, and joyful TDD. If you’re tired of slow suites or static‑mocking hacks, give it a try!
- GitHub:
- NuGet:
Feedback welcome — what pains do you have with current mocking libs? Would you switch for native statics and this speed?
⭐️ Star the repo if you like it, and let’s make testing fun again! 🚀