Understanding Method Invocation Verification with Moq's Verifiable Constructs
Ensuring Method Calls in Unit Tests with Moq's Verifiable Constructs
Introduction
I encountered a scenario where I needed to test if a method inside another method was actually invoked. This led me to learn about the Verifiable
construct in the Moq library. ๐ป It provides a concrete way to ensure that the calls configured in the mock object are indeed invoked. โน
Example ๐
Suppose a CartsController
has a CreateOrder
method that calls the GetCartItems
method within it:
public async Task<IActionResult> CreateOrder(OrderViewModel orderViewModel)
{
var cartItems = await _cartService.GetCartItems(orderViewModel.CartId);
// More codes...
return View("OrderCreated");
}
A unit test for this method can be written to verify whether GetCartItems
is actually invoked or not. Let's see how we can achieve this.
How to do? ๐คทโโ๏ธ
Mark the mock setup for the method as Verifiable
and then call the Verify
method on the mock object.
Here is a code snippet for one unit test case:
// Mock setup inside the unit test for the GetCartItems method.
_cartServiceMock.Setup(x => x.GetCartItems(It.IsAny<int>())).ReturnsAsync(() => cartItems).Verifiable();
// The following CreateOrder calls the GetCartItems inside it.
var result = await cartsController.CreateOrder(orderModel);
// Now we can verify
_cartServiceMock.Verify();
Notice that we set up a method GetCartItems
to be Verifiable. Then, we called the method inside the CartsController
to create an order. The CreateOrder
method calls the GetCartItems
method inside it.
So, _cartServiceMock.Verify();
will now be successful as it invoked the GetCartItems
method.
If for some reason it does not, then the test will throw an exception like in the following screenshot.
Feedback
I hope it is clear. Let me know if you have any doubts. ๐ช Share, if you care. ๐