Roadmap › Clean Code, Testing & Best Practices › Module: Testing
Lessons in this course (12)
8. Mocking with Moq / NSubstitute
Intermediate★ Must knowLesson 8 of 12
csharp
[Fact]
public async Task PlaceOrder_saves_and_sends_confirmation()
{
var repo = new Mock<IOrderRepository>();
var email = new Mock<IEmailSender>();
var sut = new OrderService(repo.Object, email.Object);
await sut.PlaceAsync(new Order(1, 500m));
repo.Verify(r => r.AddAsync(It.Is<Order>(o => o.Id == 1)), Times.Once);
email.Verify(e => e.SendAsync(It.IsAny<string>(), It.IsAny<string>()), Times.Once);
}
// NSubstitute equivalent
var repo2 = Substitute.For<IOrderRepository>();
await repo2.Received(1).AddAsync(Arg.Is<Order>(o => o.Id == 1));Test doubles: Dummy (unused), Stub (returns canned data), Fake (working lightweight version, e.g. in-memory repo), Mock (verifies interactions), Spy (records calls). Don't mock what you don't own (e.g. HttpClient) — wrap it or use a fake HttpMessageHandler.