mocking a method to return different results

This week I was working on a piece of code that process batches and it had to be unit tested. Let’s think of this scenario. We have a service endpoint that creates a batch order (and a record in the database), and then for each item in that batch order it will create a product order (and again, a record in the database). If one of the product order fails, we need to revert the process, and delete all product orders together with the batch order.

Implementing it wasn’t a problem but when it came to unit testing the behaviour in the case when one product order fails, I had to think twice about it. Thankfully I discovered the SetupSequence method in the testing framework that I use (xUnit). What this method does is basically saying that when a method is called, I want the first value to be something, and the second value to be something else, in my case zero. I then decided to assert that not only the return would be zero (because the whole batch failed) but also that the method that reverts the transaction was called. Check out my implementation below;


[Fact]
public async void TheMethodImMocking_Returns_Zero_If_One_Of_The_Records_Not_Inserted()
{
// Arrange
Mock _mockDataLayerService = new Mock;
_mockDataLayerService.SetupSequence(x => x.ProcessIndividualOrder(It.IsAny())).ReturnsAsync(9999).ReturnsAsync(0);
// Act
var batchProcessingService = new BatchProcessingService(_mockDataLayerService.Object);
var result = batchProcessingService.ProcessBatchOrder()
// Assert
Assert.IsType(result);
Assert.Equal(0, result);
_mockDataLayerService.Verify(m => m.ReverseOrderProcessing(It.IsAny()), Times.Exactly(1));
}

The only catch when using the SetupSequence method is to know how many times the testable method will be called because if the return values, and the amount of calls do not match, an exception will be throw. Again, in my case I knew that I will be calling the method ProcessIndividualOrder twice so I setup the method to return a value twice.

I hope you’ll find this useful the same way I did, and happy unit testing 🙂

Bjorn

Leave a comment