Moq - Unit Test In .NET Core App Using Mock Object

The Unit test is a block of code that helps us in verifying the expected behavior of the other code in isolation; i.e., there is no dependency between the tests. This is good way to test the application code before it goes for quality assurance (QA). There are three different test frameworks for Unit Testing supported by ASP.NET Core: MSTest, XUnit, and NUnit. All Unit test frameworks, offer a similar end goal and help us to write unit tests that are simpler, easier and faster.

Introduction
 
Unit Test is a block of code that helps us in verifying the expected behavior of the other code in isolation; i.e., there is no dependency between the tests. This is a good way to test the application code before it goes for quality assurance (QA). There are three different test frameworks for Unit Testing supported by ASP.NET Core: MSTest, XUnit, and NUnit. All Unit test frameworks offer a similar end goal and help us to write unit tests that are simpler, easier and faster.
 
In my previous articles, I have explained how to write unit tests with different frameworks (i.e. MSTest, XUnit, and NUnit). These articles have a very simple and very straightforward example but in the real world, a class's constructor may have a complex object and be injected as a dependency. In this case, we can create a mock object and use it for the unit test.
 
A mock object is an object that can act as a real object but can be controlled in test code. Moq is a library that allows us to create mock objects in test code. It is also available in NuGet. This library also supports .NET Core.
 
The Moq library can be added to test projects either by package manager or .NET CLI tool.
 
Using Package Manager
  1. PM> Install-Package Moq  
Using .net core CLI
  1. dotnet add package Moq  
In the following example, controller class required constructor dependency to create the instance.
 
MVCProject/Core/IGetDataRepository.cs
  1. namespace MVCproject.Core  
  2. {  
  3.     public interface IGetDataRepository  
  4.     {  
  5.         string GetNameById(int id);  
  6.     }  
  7. }   
MVCProject\Infrastructure\EmployeeRepository.cs
  1. using MVCproject.Core;  
  2. namespace MVCproject.Infrastructure  
  3. {  
  4.     public class EmployeeRepository : IGetDataRepository  
  5.     {  
  6.         public string GetNameById(int id)  
  7.         {  
  8.             string name;  
  9.             if (id == 1)  
  10.             {  
  11.                 name = "Jignesh";  
  12.             }  
  13.             else if (id == 2)  
  14.             {  
  15.                 name = "Rakesh";  
  16.             }  
  17.             else  
  18.             {  
  19.                 name = "Not Found";  
  20.             }  
  21.             return name;  
  22.         }  
  23.     }  
  24. }  
MVCProject\Controllers\HomeController.cs
  1. using Microsoft.AspNetCore.Mvc;  
  2. using MVCproject.Core;  
  3.   
  4. namespace MVCProject.Controllers  
  5. {  
  6.     public class HomeController : Controller  
  7.     {  
  8.         private readonly IGetDataRepository _data;  
  9.   
  10.         public HomeController(IGetDataRepository data)  
  11.         {  
  12.             _data = data;  
  13.         }  
  14.   
  15.         public IActionResult Index()  
  16.         {  
  17.             return View();  
  18.         }  
  19.   
  20.         public string GetNameById(int id)  
  21.         {  
  22.             return _data.GetNameById(id);  
  23.         }  
  24.     }  
  25. }  
Here, to create controller class instance, we require the object of IGetDataRepository. Without a mock object, we need to create object of IGetDataRepository which is real.
 
Moq library allows us to manipulate the mock object in many ways, such as setting mock methods to return specific values, setting up required properties, and matching the specific arguments when test method is called mock object.
 
Moq can create a mock version of IGetDataRepository. To demonstrate the code, I am using MSTest framework. In this example, I am using Setup and Returns methods to create a mock object. The Setup method is used to tell the mock object how to behave when it calls for test method and return methods returns a specific value.
 
MockingUnitTest\MSTestProject\UnitTest1.cs
  1. using Microsoft.VisualStudio.TestTools.UnitTesting;  
  2. using MVCProject.Controllers;  
  3. using Moq;  
  4. using Microsoft.Extensions.Logging;  
  5. using MVCproject.Core;  
  6. using MVCproject.Controllers;  
  7. namespace TestProject  
  8. {  
  9.     [TestClass]  
  10.     public class UnitTest1  
  11.     {  
  12.         [TestMethod]  
  13.         public void TestMethod2()  
  14.         {  
  15.             var mock = new Mock<IGetDataRepository>();  
  16.             mock.Setup(p => p.GetNameById(1)).Returns("Jignesh");  
  17.             HomeController home = new HomeController(mock.Object);  
  18.             string result = home.GetNameById(1);  
  19.             Assert.AreEqual("Jignesh", result);  
  20.         }  
  21.     }  
  22. }  
The Moq library is rge same for all the unit test framework. It means that the above test will work with XUnit and NUnit after some syntax modification.
 
Summary
 
The Unit test is code where we test all the code paths of the methods and ensure that the results are as expected. Mock object is the object that can act as a real object but can be controlled in test code. It is very useful in generating the objects which are used in test method.
 
You can view or download source code from here.