Introduction
Moq leverages .NET lambda expressions to provide a clean, type-safe API for creating mock objects. Instead of generating code or using record/replay semantics, you set up expectations inline with your test logic, making tests more readable and maintainable.
What Moq Does
- Creates mock implementations of interfaces and virtual methods at runtime
- Sets up return values, callbacks, and sequences using lambda expressions
- Verifies that specific methods were called with expected arguments
- Supports loose and strict mock behavior modes
- Handles async methods, properties, events, and generic types
Architecture Overview
Moq generates proxy classes at runtime using Castle DynamicProxy. When you call new Mock<T>(), it creates a transparent proxy that intercepts method calls and matches them against your setup expressions. The lambda-based API is parsed at compile time for type safety, while the proxy infrastructure handles dispatch at runtime. No code generation step or external tools are needed.
Self-Hosting & Configuration
- Install via NuGet:
dotnet add package Moq - Compatible with xUnit, NUnit, MSTest, and any .NET test framework
- Targets .NET Standard 2.0 and .NET Standard 2.1
- Configure default behavior with
MockBehavior.Loose(default) orMockBehavior.Strict - Use
MockRepositoryto batch-verify multiple mocks in a single call
Key Features
- Type-safe lambda-based setup and verification syntax
- Argument matchers:
It.IsAny<T>(),It.Is<T>(predicate),It.IsRegex() - Sequential return values with
SetupSequencefor stateful scenarios - LINQ-to-Mocks for declarative mock creation
- Protected member mocking via
mock.Protected()API
Comparison with Similar Tools
- NSubstitute — similar fluent API with slightly less ceremony; Moq has broader community adoption
- FakeItEasy — call-configuration style; Moq uses lambda setup which some find more discoverable
- Rhino Mocks — legacy record/replay pattern; Moq replaced it with a simpler lambda model
- JustMock (Telerik) — commercial with free tier; can mock non-virtual and static members
- Microsoft Fakes — Visual Studio Enterprise only; supports shims for static and sealed types
FAQ
Q: Can Moq mock concrete classes? A: Moq can mock classes with virtual methods. Non-virtual or sealed members cannot be intercepted by the runtime proxy.
Q: How do I mock async methods?
A: Use ReturnsAsync() for Task-returning methods: mock.Setup(x => x.GetAsync(1)).ReturnsAsync(result);
Q: What is the difference between Loose and Strict mode? A: Loose mode returns default values for unsetup calls. Strict mode throws an exception if a call has no matching setup, helping you catch unexpected interactions.
Q: Is Moq still actively maintained? A: Yes. After a brief community concern in 2023, the project continues under active development with regular releases.