In this lesson, you will learn how to decouple your logic from external dependencies by dynamically generating object doubles using Moq and NSubstitute.
Up until now, you have likely been manually creating "Fakes" or "Stubs" by implementing interfaces yourself. While this works for simple cases, it becomes tedious as your system grows. Moq and NSubstitute allow you to generate these test doubles at runtime, enabling you to isolate the "System Under Test" (SUT) from infrastructure concerns like database access, API calls, or file systems.
The Power of Dynamic Doubles
A mocking framework acts as a factory for interface implementations. Instead of writing a custom FakeOrderRepository, you tell the library to provide an object that implements IOrderRepository and dictate how that object should behave during the test execution.
Moq Example
Moq uses a "Setup" and "Verify" syntax. You define the expectation of an interaction before the code runs:
var mockRepo = new Mock<IOrderRepository>();
mockRepo.Setup(repo => repo.GetById(1)).Returns(new Order { Id = 1 });
var service = new OrderService(mockRepo.Object);
service.Process(1);
mockRepo.Verify(repo => repo.GetById(1), Times.Once);
NSubstitute Example
NSubstitute favors a more natural, fluent syntax that feels like native C#:
var substituteRepo = Substitute.For<IOrderRepository>();
substituteRepo.GetById(1).Returns(new Order { Id = 1 });
var service = new OrderService(substituteRepo);
service.Process(1);
substituteRepo.Received().GetById(1);
Why Use These?
The primary advantage here is decoupling. When you use a mocking framework, your tests remain focused on the behavior of the SUT rather than the implementation details of the dependency. If you add a new method to IOrderRepository, your manual fake would break and require a recompile; with Moq or NSubstitute, you only update the specific tests that interact with that new method.
By abstracting the external dependency, you ensure that your unit tests are fast, deterministic, and verify exactly what your class does with the data it receives, rather than testing the reliability of the external service itself.
Key Takeaway: Moq and NSubstitute replace manual test doubles with dynamic proxies, allowing you to isolate logic and verify interactions without boilerplate code.