Welcome to the “Fundamentals of Unit Testing” article series, in our previous article we learned many interesting concepts of unit testing. You can read them here.
In this article we will discuss one very important concept called mocking in unit testing. Let's discuss, why mocking is needed the actual uses of it, and how it comes into unit testing scenarios.
What is mocking?
Let's think that one application is being developed and many developers are working in this project and each one is assigned to develop a function. Let's think that I am developing a function that will insert one employee's information into the DB; if it is not present in the DB then fine and one of my fellow developer is developing the function to check the existence.
And I have completed my function but this guy has not, as he has a little bit of a workload, haha.. Now, as I completed my task, I wanted to test my function but for that, I need to depend on the checking function that is still not developed.
So, how I will do that? I need to create a mock object that will bypass the checking function. The point to make here is that there are many mocking frameworks to implement the mock object. In this article, we will use MOQ as a mocking framework.
So, let's create one unit test application and pass this library as a reference of the application from the NuGet Package Manager.
Here is the code that we will test using the unit test application.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestProjectLibrary
{
public class checkEmployee
{
public virtual bool checkEmp()
{
throw new NotImplementedException();
}
}
public class processEmployee
{
public bool insertEmployee(checkEmployee objtmp)
{
objtmp.checkEmp();
return true;
}
}
}
Now, see the implementation, the checkEmployee class contains a checkEmp() function that is still not implemented. We are sending an object of the checkEmployee class to the insertEmployee() function to check whether the employee already exists before it is inserted into the DB.
So, the concept is that since the checkEmployee class is not fully implemented, we will send a mock object of the checkEmployee class as an argument of the insertEmployee() function. Here is a sample code of the implementation.
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TestProjectLibrary;
using Moq;
namespace UnitTest
{
[TestClass]
public class UnitTest
{
[TestMethod]
public void TestMethod2()
{
Mock<checkEmployee> chk = new Mock<checkEmployee>();
chk.Setup(x => x.checkEmp()).Returns(true);
processEmployee obje = new processEmployee();
Assert.AreEqual(obje.insertEmployee(chk.Object), true);
}
}
}
Have a look at the first two lines of TestMethod2(). We are defining a mock object associated with the checkCmployee class and in the next line, we are setting the mock object.
chk.Setup(x => x.checkEmp())
.Returns(true);
The preceding line is a bit interesting. Moq has a Setup() function by which we can set up the mock object. We need to use a lambda expression to point to a specific function. Here we are referring to the checkEmp() function and the Returns parameter value is true.
This means that whenever the unit test application encounters the checkEmp() function it will always return true without executing its code. So, ultimately, it will not execute at all and the result will be always true.
Now, if we run the test then we will see it passes.
Conclusion
Mocking is very useful concept when the project is distributed among many team members. The fundamental idea behind mocking is to inject dependency and perform a unit test.