C# Programming
Published in

C# Programming

How to Mock for Unit Testing

Photo from: https://www.functionize.com/blog/importance-upstream-unit-testing/

I have got the discussion with my colleague about unit testing with some scenario that his/her target function will involved into others teams APIs but not ready yet. But he/she already completed the logic of demand function(s) and want to validate with unit testing and perform integration test later after every all settle down.

We think that for the case we could introduce some mock service(s) for the current stage to accomplishment the unit test and verify the logic from our end merely.

The story will demonstrate the simply example that how to adopt mock concept into the case and so that we could focus and control the development process in the easy approach😊.

Suppose we have implemented the shopping cart service with following steps:

  1. Ensure user in login status.
  2. Ensure the item(s) amount of stock on hand.
  3. Calculate totals amount for the item(s).
  4. Select available payment gateway.
  5. Validate the payment status.
  6. Others…..

And for the payment affairs, we might need to connected to others team’s (or third party(s)) API for completed the payment process and check out process for the deal.

According above scenario that we have simply the below interface, we need implement ICartService for the function of Checkout. and we will inject IPaymentService for handling payment relative processes.


public interface IPaymentService
{
ResultModel Pay(List<Item> Items);
}
public interface ICartService
{
ResultModel Checkout(List<Item> Items);
}

So the pseudo code might look as below:

public class CartService : ICartService
{
private readonly IPaymentService _paymentService;
public CartService(IPaymentService paymentService)
{
_paymentService = paymentService;
}

public ResultModel Checkout(List<Item> items)
{
// check user status and inventory status
// ...

// everything would looks fine, invoke payment service
var payResult = _paymentService.Pay(items);

// so far if pay result was completed then
// inform warehouse and packing to the rest of processes
// ...
}}

Next, we create the Microsoft unit test project (see guide here) and installed the mock library: moq that help us setup mock service for payment.


[TestClass]
public class ECServiceUinitTest
{
private ICartService _cartService;
private Mock<IPaymentService> _mockPaymentService;
[TestInitialize]
public void Initialize()
{
// config model
var configModelOptions = new ConfigModel()
{
ApiKey = "....",
};

// new mock object for IPaymentService
_mockPaymentService = new Mock<IPaymentService>(MockBehavior.Strict);
// new cart service and passing config model
// and mock object for DI
_CartService = new CartService(configModelOptions, _mockPaymentService.Object);
} [TestMethod]
// Test for checkout function with success case
public void Test_Checkout_Cart_Return_Success()
{
// arrange
var item1 = new Item() {Name = "IPhone12", Price = 1000};
var item2 = new Item() {Name = "IWatch6", Price = 500}; var items = List<Item>() {item1, item2};

// setup mock method: Pay to return success for any input
// so that we could focus testing our cart service
_mockPaymentService.Setup(e => e.Pay(It.IsAny<List<Item>>())).Returns(
new ResultModel()
{
Status = "Success"
});
// actual
var result = _cartService.Checkout(items).GetAwaiter().GetResult();
// assert
Assert.AreEqual("Success", result.Status);
}
}

As the example demonstrate that we could easily setup the behavior of mock object for different test case(s). No matter for the normal successful flow or any edge cases (even failed scenario).

I’m not a great programmer; I’m just a good programmer with great habits. ― Kent Beck

Writing a unit test is a great habits and also a way to solid your application as well😃.

Reference

Focuses on ASP.Net | ASP.Net Core | .Net & C# advance design, best practices & experiences to make developers life simple..!!

Recommended from Medium

GitHub Actions, ViteJS, DevOps Exercises and about SRECon21

Publishing Tips and Discussing Questions about Inheritance and Polymorphism in Java

Ubuntu 20.04中實用指令(會持續更新)|Practical commands in Ubuntu 20.04 (To be continued...)

Improve your software quality with Property-Based Testing

Rebuilding Facebook — Fluency in Programming

Here’s How I Optimized Tracking Project Evolution — CHANGELOG.md

Firebase CRUD Operations With Flutter Part 1 (Document Reference)

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
LAI TOCA

LAI TOCA

Coding for fun

More from Medium

3+3 ASP.NET Mistakes (+ How to avoid them)

Creating static IP proxy for C# run in GCE using squid.

How to use the IEquatable <>— .Equals() .Net6

Design Best Practices In .NET C#

Design Best Practices In DotNet (.NET) CSharp (C#). Dependency Injection (DI) Inversion of Control (IoC) IoC Containers Delegate Interface Event Snapshot Immutable Strategy Pattern Strategy State Behavior Software Architecture Engineering Development Code Coding Programming Paging