Table of Contents
- Introduction
- Roadmap
- Unit Tests
- NUnit
- Moq Framework
- Setup Solution
- Testing Business Services
- Step 1: Test Project
- Step 2: Install the NUnit package
- Step 3: Install the Moq framework
- Step 4: Install Entity Framework
- Step 5: Install AutoMapper
- Step 6: References
- TestHelper
- ProductService Tests
- Tests Setup
- Declare variables
- Write Test Fixture Setup
- Write Test Fixture Tear Down
- Write Test Setup
- Write Test Teardown
- Mocking Repository
- Initialize UnitOfWork and Service
GetAllProductsTest() GetAllProductsTestForNull() GetProductByRightIdTest() GetProductByWrongIdTest() AddNewProductTest() UpdateProductTest() DeleteProductTest()
- TokenService Tests
- Tests Setup
- Declare variables
- Write Test Fixture Setup
- Write Test Fixture Tear Down
- Write Test Setup
- Write Test Teardown
- Mocking Repository
GenerateTokenByUseridTest() ValidateTokenWithRightAuthToken() ValidateTokenWithWrongAuthToken()
- UserService Tests
- WebAPI Tests
- Conclusion
- Tests Setup
Introduction
We have been learning a lot about Web API. We covered almost all the techniques required to build a robust and full-stack REST service using asp.net Web API, right from creating a service to making it a secure and ready-to-use boilerplate with enterprise-level applications. In this article, we’ll learn on how to focus on test-driven development and write unit tests for our service endpoints and business logic. I’ll use the NUnit and Moq framework to write test cases for the business logic layer and controller methods. I’ll cover less theory and focus more on practical implementations of how to use these frameworks to write unit tests. I have segregated the article into two parts. The first part focuses on testing business logic and class libraries created as BusinessServices in our code base. The second part will focus on testing a Web API. The purpose of segregation is simple; the scope of this article is very large and may turn up into a very large post which would not be easy to read in a go.
Roadmap
The following is the roadmap I have set to learn Web API step by step.

- RESTful Day #1: Enterprise-level application architecture with Web APIs using Entity Framework, Generic Repository pattern, and Unit of Work.
- RESTful Day #2: Inversion of control using dependency injection in Web APIs using Unity Container and Bootstrapper.
- RESTful Day #3: Resolve dependency of dependencies using Inversion of Control and dependency injection in ASP.Net Web APIs with Unity Container and Managed Extensibility Framework (MEF).
- RESTful Day #4: Custom URL Re-Writing/Routing using Attribute Routes in MVC 4 Web APIs.
- RESTful Day #5: Basic Authentication and Token-based Custom Authorization in Web APIs using Action Filters.
- RESTful Day #6: Request logging and Exception handing/logging in Web APIs using Action Filters, Exception Filters, and NLog.
- RESTful Day #7: Unit Testing and Integration Testing in WebAPI using NUnit and Moq framework (Part 1).
- RESTful Day #8: Unit Testing and Integration Testing in WebAPI using NUnit and Moq framework (Part 2).
- RESTful Day #9: Extending OData support in ASP.NET Web APIs.
I’ll purposely use Visual Studio 2010 and .net Framework 4.0 because there are a few implementations that are very hard to find in .Net Framework 4.0, but I’ll make it easy by showing how we can do it.
Unit Tests
“Unit tests allow you to make big changes to code quickly. You know it works now because you’ve run the tests, when you make the changes you need to make, you need to get the tests working again. This saves hours.” I got this from a post at Stack Overflow, and I completely agree with this statement.

A good unit test helps a developer to understand his code and most importantly the business logic. Unit tests help to understand all the aspects of business logic, right from the desired input and output to the conditions where the code can fail. A code having a well written unit tests has very little chance of failure provided the unit tests cover all the test cases required to execute.
NUnit
There are various frameworks available for Unit tests. NUnit is the one that I prefer. NUnit gels well with .Net and provides flexibility to write unit tests without hassle. It has meaningful and self-explanatory properties and class names that help the developer write the tests in an easy way. NUnit provides an easy-to-use interactive GUI where you can run the tests and get the details. It shows the number of tests passed or failed in a beautiful fashion and also gives the stack trace in case any test fails, thereby enabling you to perform the first level of debugging at the GUI itself. I suggest downloading and installing NUnit on your machine for running the tests. We’ll use NUnit GUI after we write all the tests. I normally use the inbuilt GUI of NUnit provided by Re-sharper integrated into my Visual Studio. Since Re-sharper is a paid library only a few developers may have it integrated, so I suggest you use NUnit GUI to run the tests. Since we are using Visual Studio 2010, we need to use the older version of NUnit i.e. 2.6.4. You can download and run the .msi and install it on your machine following this URL.

Once you finish installation, your NUnit is installed in your installed items on your machine as shown below image.

Moq Framework
Moq is a simple and straightforward library to mock the objects in C#. We can mock data, repositories classes, and instances with the help of a mock library. So when we write unit tests, we do not execute them on the actual class instances, instead perform in-memory unit testing by making a proxy of class objects. Like NUnit, Moq library classes are also easy to use and understand. Almost all of its methods, classes, and interface names are self-explanatory.
The following is the list taken from Wikipedia on why to use mock objects,
- The object supplies non-deterministic results (e.g., the current time or the current temperature);
- Has states that are not easy to create or reproduce (e.g., a network error);
- Is slow (e.g., a complete database, which would have to be initialized before the test);
- Does not yet exist or may change behavior;
- Would have to include information and methods exclusively for testing purposes (and not for its actual task).
So whatever test we write, we actually execute that on test data and proxy objects i.e. not the instances of real classes. We’ll use Moq to mock data and repositories so that we do not hit database again and again for executing unit tests. You can read more about Moq in this article.
Setup Solution
I’ll use this article to explain how to write unit tests for business logic i.e. covering our business logic layer and for WebAPI controllers. The scope of Unit tests should not be only limited to business logic or endpoints but should spread over all publically exposed logics like filters and handlers as well. Well written unit tests should cover almost all the code. One can track the code coverage through some of the tools available online. We’ll not test filters and common classes but will focus on controllers and business logic layer and get an idea of how to proceed with unit tests. I’ll use the same source code that we used till Day# 6 of the series and will proceed with the latest code base that we got out of last article of the series. Code base is available for download with this post. When you take the code base from my last article and open it in visual studio, you’ll see the project structure something like as shown in below image,

IUnitOfWork is the new interface that I have added just to facilitate interface driven development. It helps in mocking objects and improved structure and readability. Just open the visual studio and add a new interface named IUnitOfWork under UnitOfWork folder in DataModel project and define the properties used in UnitOfWork class as shown below,

Now, go to the UnitOfWork class and inherit that class using this interface, so the UnitOfWork class becomes something like this.
#region Using Namespaces...
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Diagnostics;
using System.Data.Entity.Validation;
using DataModel.GenericRepository;
#endregion
namespace DataModel.UnitOfWork
{
/// <summary>
/// Unit of Work class responsible for DB transactions
/// </summary>
public class UnitOfWork : IDisposable, IUnitOfWork
{
#region Private member variables...
private readonly WebApiDbEntities _context = null;
private GenericRepository<User> _userRepository;
private GenericRepository<Product> _productRepository;
private GenericRepository<Token> _tokenRepository;
#endregion
public UnitOfWork()
{
_context = new WebApiDbEntities();
}
#region Public Repository Creation properties...
/// <summary>
/// Get/Set Property for product repository.
/// </summary>
public GenericRepository<Product> ProductRepository
{
get
{
if (this._productRepository == null)
this._productRepository = new GenericRepository<Product>(_context);
return _productRepository;
}
}
/// <summary>
/// Get/Set Property for user repository.
/// </summary>
public GenericRepository<User> UserRepository
{
get
{
if (this._userRepository == null)
this._userRepository = new GenericRepository<User>(_context);
return _userRepository;
}
}
/// <summary>
/// Get/Set Property for token repository.
/// </summary>
public GenericRepository<Token> TokenRepository
{
get
{
if (this._tokenRepository == null)
this._tokenRepository = new GenericRepository<Token>(_context);
return _tokenRepository;
}
}
#endregion
#region Public member methods...
/// <summary>
/// Save method.
/// </summary>
public void Save()
{
try
{
_context.SaveChanges();
}
catch (DbEntityValidationException e)
{
var outputLines = new List<string>();
foreach (var eve in e.EntityValidationErrors)
{
outputLines.Add(string.Format("{0}: Entity of type \"{1}\" in state \"{2}\" has the following validation errors:", DateTime.Now, eve.Entry.Entity.GetType().Name, eve.Entry.State));
foreach (var ve in eve.ValidationErrors)
{
outputLines.Add(string.Format("- Property: \"{0}\", Error: \"{1}\"", ve.PropertyName, ve.ErrorMessage));
}
}
System.IO.File.AppendAllLines(@"C:\errors.txt", outputLines);
throw e;
}
}
#endregion
#region Implementing IDisposable...
#region private dispose variable declaration...
private bool disposed = false;
#endregion
/// <summary>
/// Protected Virtual Dispose method
/// </summary>
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
Debug.WriteLine("UnitOfWork is being disposed");
_context.Dispose();
}
}
this.disposed = true;
}
/// <summary>
/// Dispose method
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
}
So, now all the interface members defined in IUnitOfWork are implemented in the UnitOfWork class.
public interface IUnitOfWork
{
#region Properties
GenericRepository<Product> ProductRepository { get; }
GenericRepository<User> UserRepository { get; }
GenericRepository<Token> TokenRepository { get; }
#endregion
#region Public methods
/// <summary>
/// Save method.
/// </summary>
void Save();
#endregion
}
Doing this will not change the functionality of our existing code, but we also need to update the business services with this Interface. We’ll pass this IUnitOfWork interface instance inside services constructors instead of directly using the UnitOfWork class.
private readonly IUnitOfWork _unitOfWork;
public ProductServices(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
So our User service, Token service and product service constructors becomes as shown below.
Product Service

User Service

Token Service

Testing Business Services
We’ll start writing unit tests for the BusinessServices project.
Step 1. Test Project.
Add a simple class library in the existing visual studio and name it BusinessServices.Tests. Open Tools->Library Packet Manager->Packet Manager Console to open the package manager console window. We need to install some packages before we proceed.

Step 2. Install the NUnit package.
In the package manager console, select BusinessServices.Tests as default project and write command “Install-Package NUnit –Version 2.6.4”. If you do not mention the version, the PMC (Package manage Console) will try to download the latest version of the NUnit nugget package but we specifically need 2.6.4, so we need to mention the version. The same applies to when you try to install any such package from PMC.

After successfully installed, you can see the dll reference in project references i.e. nunit. framework.

Step 3. Install the Moq framework.
Install the framework on the same project in a similar way as explained in Step 2. Write the command “Install-Package Moq”.Here we use the latest version of Moq.

Therefore added dll,

Step 4. Install Entity Framework.
Install-Package EntityFramework -Version 5.0.0
Step 5. Install AutoMapper.
Install-Package AutoMapper -Version 3.3.1
Our package.config i.e. automatically added in the project looks like.
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AutoMapper" version="3.3.1" targetFramework="net40" />
<package id="EntityFramework" version="5.0.0" targetFramework="net40" />
<package id="Moq" version="4.2.1510.2205" targetFramework="net40" />
<package id="NUnit" version="2.6.4" targetFramework="net40" />
</packages>
Step 6. References.
Add references of DataModel, BusinessServices, and BusinessEntities projects to this project.

TestHelper
We will require few helper files that would be needed in BusinessServices.Tests project and in our WebAPI.Tests project that we’ll create later. To place all the helper files, I have created one more class library project named TestHelper. Just right click the solution and add new project named TestHelper and add a class named DataInitializer.cs into it. This class contains three simple methods to fetch i.e. User’s, Product’s and Token’s dummy data. You can use the following code as the class implementation.
using System;
using System.Collections.Generic;
using DataModel;
namespace TestsHelper {
/// <summary>
/// Data initializer for unit tests
/// </summary>
public class DataInitializer {
/// <summary>
/// Dummy products
/// </summary>
/// <returns></returns>
public static List<Product> GetAllProducts() {
var products = new List<Product> {
new Product() {
ProductName = "Laptop"
},
new Product() {
ProductName = "Mobile"
},
new Product() {
ProductName = "HardDrive"
},
new Product() {
ProductName = "IPhone"
},
new Product() {
ProductName = "IPad"
}
};
return products;
}
/// <summary>
/// Dummy tokens
/// </summary>
/// <returns></returns>
public static List<Token> GetAllTokens() {
var tokens = new List<Token> {
new Token() {
AuthToken = "9f907bdf-f6de-425d-be5b-b4852eb77761",
ExpiresOn = DateTime.Now.AddHours(2),
IssuedOn = DateTime.Now,
UserId = 1
},
new Token() {
AuthToken = "9f907bdf-f6de-425d-be5b-b4852eb77762",
ExpiresOn = DateTime.Now.AddHours(1),
IssuedOn = DateTime.Now,
UserId = 2
}
};
return tokens;
}
/// <summary>
/// Dummy users
/// </summary>
/// <returns></returns>
public static List<User> GetAllUsers() {
var users = new List<User> {
new User() {
UserName = "akhil",
Password = "akhil",
Name = "Akhil Mittal",
},
new User() {
UserName = "arsh",
Password = "arsh",
Name = "Arsh Mittal",
},
new User() {
UserName = "divit",
Password = "divit",
Name = "Divit Agarwal",
}
};
return users;
}
}
}
In the above class, GetAllUsers() fetches dummy data for users, GetAllProducts() fetches dummy data for Products and GetAllTokens() method fetches dummy data for Tokens. So now, our solution has two new projects as shown below.

Add DataModel project reference to TestHelper project and TestHelper project reference to BusinessServices.Tests project.


ProductServiceTests
We’ll start with setting up the project and setting up the prerequisites for tests and gradually move on to actual tests.
Tests Setup
We’ll proceed with creatingProductServices tests. Add a new class named ProductServicesTests.cs in BusinessServices.Tests project.
Declare variables
Define the private variables that we’ll use in the class to write tests.
#region Variables
private IProductServices _productService;
private IUnitOfWork _unitOfWork;
private List<Product> _products;
private GenericRepository<Product> _productRepository;
private WebApiDbEntities _dbEntities;
#endregion
Variable declarations are self-explanatory where _productService will hold mock for ProductServices, _unitOfWork for UnitOfWork class, _products will hold dummy products from DataInitializer class of TestHelper project, _productRepository and _dbEntities holds mock for Product Repository and WebAPIDbEntities from DataModel project respectively
Write Test Fixture Setup
Test fixture setup is written as a one-time setup for all the tests. It is like a constructor in terms of classes. When we start executing setup, this is the first method to be executed. In this method we’ll populate the dummy products data and decorate this method with the [TestFixtureSetUp] attribute at the top that tells compiler that the particular method is a TestFixtureSetup. [TestFixtureSetUp] attribute is the part of NUnit framework, soinclude it in the class as a namespace i.e. using NUnit.Framework;. The following is the code for TestFixtureSetup.
#region Test fixture setup
/// <summary>
/// Initial setup for tests
/// </summary>
[TestFixtureSetUp]
public void Setup()
{
_products = SetUpProducts();
}
#endregion
private static List<Product> SetUpProducts()
{
var prodId = new int();
var products = DataInitializer.GetAllProducts();
foreach (Product prod in products)
prod.ProductId = ++prodId;
return products;
}
SetUpproducts() method fetches products from the DataInitializer class and not from the database.It also and assigns a unique id to each product by iterating them.The result data is assigned to _products list to be used in setting up mock repository and in every individual test for comparison of actual vs resultant output.
Write Test Fixture Tear Down
Unlike TestFixtureSetup, tear down is used to de-allocate or dispose the objects.It also executes only one time when all the tests execution ends. In our case we’ll use this method to nullify _products instance. The attribute used for Test fixture tear down is [TestFixtureTearDown].
The following is the code for teardown.
#region TestFixture TearDown.
/// <summary>
/// TestFixture teardown
/// </summary>
[TestFixtureTearDown]
public void DisposeAllObjects()
{
_products = null;
}
#endregion
Note that we have till now not written any unit test.
Write Test Setup
TestFixtureSetUpis a one-time run process where as [SetUp] marked method is executed after each test. Each test should be independent and should be tested with a fresh set of inputs. Setup helps us to re-initialize data for each test. Therefore all the required initialization for tests are written in this particular method marked with the [SetUp] attribute. I have written a few methods and initialized the private variables in this method. These lines of code execute after each test ends so that individual tests do not depend on any other written test and do not get hampered by other test's pass or fail status. Code for Setup.
#region Setup
/// <summary>
/// Re-initializes test.
/// </summary>
[SetUp]
public void ReInitializeTest()
{
_dbEntities = new Mock<WebApiDbEntities>().Object;
_productRepository = SetUpProductRepository();
var unitOfWork = new Mock<IUnitOfWork>();
unitOfWork.SetupGet(s => s.ProductRepository).Returns(_productRepository);
_unitOfWork = unitOfWork.Object;
_productService = new ProductServices(_unitOfWork);
}
#endregion
We make use of Mock framework in this method to mock the private variable instances. Like for _dbEntities we write _dbEntities = newMock<WebApiDbEntities>().Object; . This means that we are mocking WebDbEntities class and getting its proxy object. Mock class is the class from Moq framework, so include the respective namespace using Moq; in the class.
Write Test Tear down
Like testSetup runs after every test, similarly Test [TearDown] is invoked after every test execution is complete.You can use tear down to dispose and nullify the objects that are initialized while setup.The method for tear down should be decorated with [TearDown]attribute. The following is the test tear down implementation.
/// <summary>
/// Tears down each test data
/// </summary>
[TearDown]
public void DisposeTest()
{
_productService = null;
_unitOfWork = null;
_productRepository = null;
if (_dbEntities != null)
_dbEntities.Dispose();
}
Mocking Repository
I talked about mocking the repository for the entities. I have created a method SetUpProductRepository() to mock Product Repository and assign it to _productrepository in the ReInitializeTest() method.
private GenericRepository<Product> SetUpProductRepository()
{
// Initialise repository
var mockRepo = new Mock<GenericRepository<Product>>(MockBehavior.Default, _dbEntities);
// Setup mocking behavior
mockRepo.Setup(p => p.GetAll()).Returns(_products);
mockRepo.Setup(p => p.GetByID(It.IsAny<int>()))
.Returns(new Func<int, Product>(
id => _products.Find(p => p.ProductId.Equals(id))));
mockRepo.Setup(p => p.Insert((It.IsAny<Product>())))
.Callback(new Action<Product>(newProduct =>
{
dynamic maxProductID = _products.Last().ProductId;
dynamic nextProductID = maxProductID + 1;
newProduct.ProductId = nextProductID;
_products.Add(newProduct);
}));
mockRepo.Setup(p => p.Update(It.IsAny<Product>()))
.Callback(new Action<Product>(prod =>
{
var oldProduct = _products.Find(a => a.ProductId == prod.ProductId);
oldProduct = prod;
}));
mockRepo.Setup(p => p.Delete(It.IsAny<Product>()))
.Callback(new Action<Product>(prod =>
{
var productToRemove =
_products.Find(a => a.ProductId == prod.ProductId);
if (productToRemove != null)
_products.Remove(productToRemove);
}));
// Return mock implementation object
return mockRepo.Object;
}
Here we mock all the required methods of Product Repository to get the desired data from _products object and not from the actual database.
The single line of code
var mockRepo = new Mock<GenericRepository<Product>>(MockBehavior.Default, _dbEntities);
mocks the Generic Repository for Product and mockRepo.Setup() mocks the repository methods by passing relevant delegates to the method.
Initialize UnitOfWork and Service
I have written the following lines of code in the ReInitializeTest() method i.e. our setup method.
var unitOfWork = new Mock<IUnitOfWork>();
unitOfWork.SetupGet(s => s.ProductRepository).Returns(_productRepository);
_unitOfWork = unitOfWork.Object;
_productService = new ProductServices(_unitOfWork);
Here you can see that I am trying to mock the UnitOfWork instance and forcing it to perform all its transactions and operations on _productRepository that we have mocked earlier. This means that all the transactions will be limited to the mocked repository and the actual database or actual repository will not be touched. The same goes for service as well; we are initializing product Services with this mocked _unitOfWork. So when we use _productService in actual tests, it actually works on mocked UnitOfWork and test data only.

All set now and we are ready to write unit tests for ProductService. We’ll write a test to perform all the CRUD operations that are part of ProductService.
GetAllProductsTest ()
Our ProductService in BusinessServices project contains a method named GetAllProducts (), the following is the implementation.


































Micheal OgunderoPosted Apr 14, 2021, 4:34 PM
Nice article to get on unit test
Former memberPosted Oct 9, 2020, 2:23 AM
Very Nice and fully explained article. Thanks Akhil Mittal
Bimal DasPosted Dec 15, 2018, 3:11 AM
For UserServices, I solved the issue by writing mockRepo.Setup(p => p.Get(It.IsAny<Func<User, bool>>())) .Returns((Func<User, bool> predicate) => _users.FirstOrDefault(predicate)); Also I added virtual keyword in Get method of GenericRepository
Cao FangshengPosted Aug 10, 2016, 9:29 PM
Very nice article ,thanks
Debasis SahaPosted Mar 31, 2016, 1:08 AM
Good One..
Pramod ThakurPosted Mar 7, 2016, 7:07 AM
Nice explanation..
Mohammed IbrahimPosted Mar 7, 2016, 4:09 AM
nice
Richardson dos Santos NevesPosted Mar 3, 2016, 6:50 AM
Nice article, very detailed, but not explain about tests with NUnit with WebApi, it?s a unit test for Entity Framework, not applied for consume REST WebApi actions.
Ankur MistryPosted Mar 3, 2016, 4:49 AM
appreciate your hard work. Very nice
Anu VPosted Mar 2, 2016, 11:07 PM
Nice
Gowtham KPosted Mar 2, 2016, 12:14 PM
Great Article, Thanks for sharing:)
Vivek TripathiPosted Mar 2, 2016, 8:45 AM
Wow, gr8 article, thanks :)
Sibeesh VenuPosted Mar 2, 2016, 8:21 AM
Nice Share
Vignesh ManiPosted Mar 2, 2016, 6:47 AM
Good
Mohammed IbrahimPosted Mar 2, 2016, 2:51 AM
nice
Jaipal ReddyPosted Mar 1, 2016, 11:20 PM
Thanks for sharing. .
Asfend YarPosted Mar 1, 2016, 2:08 PM
very nice