Moq
02 / 02

Moq: Async Mocks, Callbacks & Strict Mode

Moq: Async Mocks, Callbacks & Strict Mode

Mocking Async Methods

// .ReturnsAsync() is shorthand for .Returns(Task.FromResult(value)),
// tailored for mocking Task<T>-returning async methods
mockRepo.Setup(r => r.GetUserByIdAsync(1))
        .ReturnsAsync(new User { Id = 1, Name = "Alice" });

var user = await service.GetUserAsync(1);

Capturing Arguments with .Callback()

User savedUser = null;

// Callback() runs custom code on each call -- useful for capturing
// the actual arguments for later, more detailed assertions
mockRepo.Setup(r => r.Save(It.IsAny<User>()))
        .Callback<User>(u => savedUser = u);

service.SaveUser(new User { Name = "Bob" });

Assert.Equal("Bob", savedUser.Name);

MockBehavior.Strict vs. Loose

// Loose (default) -- an unconfigured member call returns a default
// value (null, 0, empty collection) instead of throwing
var looseMock = new Mock<IUserRepository>();

// Strict -- calling any member WITHOUT an explicit Setup() throws,
// surfacing unexpected/unaccounted-for interactions more aggressively
var strictMock = new Mock<IUserRepository>(MockBehavior.Strict);

Why Interfaces (Not Sealed Classes)

Moq generates a runtime dynamic proxy that inherits from (or implements) the mocked type to intercept calls. A sealed class can't be inherited from at all in .NET, so it can't be mocked directly -- code that needs to be mockable should depend on an interface (IPaymentProcessor) rather than a sealed concrete class (PaymentProcessor). For a plain class, only virtual members can be mocked, since Moq's proxy needs to override them.

MockRepository for Multiple Related Mocks

var repo = new MockRepository(MockBehavior.Strict);
var mockUserRepo = repo.Create<IUserRepository>();
var mockEmailService = repo.Create<IEmailService>();

// ... configure and exercise both mocks ...

// Verifies every setup across BOTH mocks in one call
repo.VerifyAll();

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free