Mock an update method returning a void with Moq
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
When a method returns void, there is no value to configure with .Returns(). In Moq, you test a void method by verifying that it was called, by capturing its arguments with .Callback(), or by configuring it to throw so you can exercise error paths.
Start with Verification
Suppose you have a repository with a void update method:
A basic test usually does not need a return setup at all:
For void methods, verification is usually the core assertion.
Use .Callback() to Capture Arguments
If you want to inspect what was passed to the void method, use .Callback():
This is useful when the argument values are part of the behavior under test.
Simulate Errors with .Throws()
Void methods can still throw exceptions, and tests often need to simulate that:
This is how you test the service's error path even though the mocked method itself has no return value.
Verify Call Counts
If the important behavior is how often the void method was called, verify that explicitly:
Being explicit about Times.Once, Times.Never, or Times.Exactly(n) makes the test intention clearer.
Strict vs Loose Mocks
By default, Moq uses loose behavior. That means an unconfigured void method call usually succeeds silently. If you switch to MockBehavior.Strict, unconfigured calls throw MockException.
That choice affects how much setup you need:
- loose mocks are more forgiving
- strict mocks make unexpected calls visible immediately
Void methods are often where this difference becomes very noticeable.
Async Is Different: Task Is Not void
If the method returns Task, it is not a void method anymore. Then you do use .Returns(...):
That difference matters because many people say "async void-like" when the method actually returns Task.
Common Pitfalls
- Trying to use
.Returns()on a true void method. - Forgetting to verify the call after the action under test runs.
- Relying on loose mocks and assuming a void method was called without checking.
- Using
.Callback()with argument types that do not match the mocked signature. - Confusing a
Task-returning method with a real void method.
Summary
- Void methods are tested through verification, callbacks, and exception simulation.
- Use
.Verify()to assert that the method was called with the expected arguments and count. - Use
.Callback()when you need to inspect the passed values. - Use
.Throws()to simulate failure paths. - If the method returns
Task, treat it as async work and configure it with.Returns(Task.CompletedTask).

