Table of Contents
- Introduction
- Roadmap
- Setup Solution
- Testing WebAPI
- Step 1: Test Project
- Step 2: Install the NUnit package
- Step 3: Install the Moq framework
- Step 4: Install Entity Framework
- Step 5: Newtonsoft.Json
- Step 6: References
- ProductController Tests
- Tests Setup
- Declare variables
- Write Test Fixture Setup
- Write Test Fixture Tear Down
- Write Test Teardown
- Mocking Repository
- GetAllProductsTest ()
- GetProductByIdTest ()
- Testing Exceptions from WebAPI
- GetProductByWrongIdTest ()
- GetProductByInvalidIdTest ()
- CreateProductTest ()
- UpdateProductTest ()
- DeleteProductTest ()
- DeleteInvalidProductTest ()
- DeleteProductWithWrongIdTest ()
- Integration Tests
- Difference between Unit tests and Integration tests
- Conclusion
Introduction
In my last article, I explained how to write unit tests for the business service layer. In this article, we’ll learn how to write unit tests for WebAPI controllers i.e. REST’s actual endpoints. I’ll use the NUnit and Moq framework to write test cases for controller methods. I have already explained about installing NUnit and configuring unit tests. My last article also covered explaining about NUnit attributes used in writing unit tests. Please go through my last article of the series before following this article.
Roadmap
The following is the roadmap I have set up to learn WebAPI 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 (Part1)
- 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.
Setup Solution
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 the below image,

The solution contains the WebAPI application and related projects. There are two newly added projects namedBusinessServices.Tests and TestHelper.We’ll use the TestHelper project and its classes for writing WebAPI unit tests in the same way we used it for writing business services unit tests.
Testing WebAPI
Step 1. Test Project
Add a simple class library in the existing visual studio and name it ApiController.Tests. Open Tools->Library Packet Manager->Packet Manager Console to open the package manager console window. We need to install the same packages as we did for business services before we proceed.

Step 2. Install the NUnit package.
In the package manager console, select ApiController.Tests as default project and write command “Install-Package NUnit –Version 2.6.4”. When you run the command, it says NUnit is already installed, that’s because we installed this package for BusinessServices.Tests project, but doing this again for a new project (in our case it is ApiController.Tests) will not install it again but add a reference to the NUnit framework library and mark an entry in packages. config for ApiController. Tests project.

After it's successfully installed, you can see the dll reference in project references i.e. unit. framework.
Step 3. Install Moq framework
Install the framework on the same project in the similar way as explained in Step 2. Write the command “Install-Package Moq”.

Step 4. Install Entity Framework
Install-Package EntityFramework -Version 5.0.0

Step 5. Newtonsoft.Json
Json.NET is a popular high-performance JSON framework for . NET. We’ll use it for serializing/de-serializing requests and responses.
Install-Package Newtonsoft.Json -Version 4.5.11

Our packages.config i.e. automatically added in the project looks like.
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="EntityFramework" version="5.0.0" targetFramework="net40" />
<package id="Moq" version="4.2.1510.2205" targetFramework="net40" />
<package id="Newtonsoft.Json" version="4.5.11" targetFramework="net40" />
<package id="NUnit" version="2.6.4" targetFramework="net40" />
</packages>
Step 6. References
Add references of BusinessEntities, BusinessServices, DataModel, TestsHelper, and WebApi project to this project.

ProductControllerTests
We’ll start with setting up the project and setting up the prerequisites for tests and gradually move on to actual tests.
Tests Setup
Add a new class named ProductControllerTest.csin ApiController.Tests project.
Declare variables
Define the private variables that we’ll use in the class to write tests.
#region Variables
private IProductServices _productService;
private ITokenServices _tokenService;
private IUnitOfWork _unitOfWork;
private List<Product> _products;
private List<Token> _tokens;
private GenericRepository<Product> _productRepository;
private GenericRepository<Token> _tokenRepository;
private WebApiDbEntities _dbEntities;
private HttpClient _client;
private HttpResponseMessage _response;
private string _token;
private const string ServiceBaseURL = "http://localhost:50875/";
#endregion
Variable declarations are self-explanatory where _productService will hold mock for ProductServices, _tokenService will hold mock for TokenServices, _unitOfWork for UnitOfWork class, _products will hold dummy products from DataInitializer class of TestHelper project, __tokens will hold dummy tokens from DataInitializer class of TestHelper project,_productRepository, tokenRepositoryand _dbEntities holds mock for Product Repository, Token Repository and WebAPIDbEntities from DataModel project respectively.
Since WebAPI is supposed to return a response in HttpResponse format _response is declared to store the returned response against which we can assert._token holds the token value after successful authentication._client and ServiceBaseURL may not be required in this article’s context, but you can use them to write integration tests that purposely use actual API URLs and test on the actual database.
Write Test Fixture Setup
Write test fixture setup method with [TestFixtureSetUp] attribute at the top, this method runs only one time when tests are executed.
[TestFixtureSetUp]
public void Setup()
{
_products = SetUpProducts();
_tokens = SetUpTokens();
_dbEntities = new Mock<WebApiDbEntities>().Object;
_tokenRepository = SetUpTokenRepository();
_productRepository = SetUpProductRepository();
var unitOfWork = new Mock<IUnitOfWork>();
unitOfWork.SetupGet(s => s.ProductRepository).Returns(_productRepository);
unitOfWork.SetupGet(s => s.TokenRepository).Returns(_tokenRepository);
_unitOfWork = unitOfWork.Object;
_productService = new ProductServices(_unitOfWork);
_tokenService = new TokenServices(_unitOfWork);
_client = new HttpClient { BaseAddress = new Uri(ServiceBaseURL) };
var tokenEntity = _tokenService.GenerateToken(1);
_token = tokenEntity.AuthToken;
_client.DefaultRequestHeaders.Add("Token", _token);
}
The purpose of this method is similar to that of the method we wrote for business services.hereSetupProducts() will fetch the list of dummy products and SetupTokens() will get the list of dummy tokens. We will try to set up a mock for the Token and Product repository as well, and after that mock UnitOfWork and set it up against already mocked token and product repository._prdouctService and _tokenService are the instances of ProductService and TokenService respectively, both initialized with mocked Unit of Work.
Following is the line of code that I would like to explain more.
var tokenEntity = _tokenService.GenerateToken(1);
_token = tokenEntity.AuthToken;
_client.DefaultRequestHeaders.Add("Token", _token);
In the above code, we are initializing the _client i.e. HttpClient with Token value in the request header. We are doing this because, if you remember about the security (Authentication and Authorization) we implemented in Product Controller, which says no request will be entertained unless it is authorized i.e. contains an authentication token in its header. So here we generate the token via TokenService’s GenerateToken() method, passing a default used id as “1”, and use that token for authorization. We require this only to perform integration testing as for unit tests we would directly be calling controller methods from our unit tests methods, but for actual integration tests, you’ll have to mock all pre-conditions before calling an API endpoint.
SetUpProducts()
private static List<Product> SetUpProducts()
{
var prodId = new int();
var products = DataInitializer.GetAllProducts();
foreach (Product prod in products)
prod.ProductId = ++prodId;
return products;
}
SetUpTokens()
private static List<Token> SetUpTokens()
{
var tokId = new int();
var tokens = DataInitializer.GetAllTokens();
foreach (Token tok in tokens)
tok.TokenId = ++tokId;
return tokens;
}
Write Test Fixture Tear Down
Unlike [TestFixtureTearDow n] ear down is used to de-allocate or dispose of the objects.
Following is the code for teardown.
[TestFixtureTearDown]
public void DisposeAllObjects()
{
_tokenService = null;
_productService = null;
_unitOfWork = null;
_tokenRepository = null;
_productRepository = null;
_tokens = null;
_products = null;
if (_response != null)
_response.Dispose();
if (_client != null)
_client.Dispose();
}
Write Test Setup
In this case, Setup is only required if you write an integration test. So you can choose to omit this.
[SetUp]
public void ReInitializeTest()
{
_client = new HttpClient { BaseAddress = new Uri(ServiceBaseURL) };
_client.DefaultRequestHeaders.Add("Token", _token);
}
Write Test Teardown
Test [TearDown] is invoked after every test execution is complete.
[TearDown]
public void DisposeTest()
{
if (_response != null)
_response.Dispose();
if (_client != null)
_client.Dispose();
}
Mocking Repository
I have created a method SetUpProductRepository() to mock Product Repository and assign it to _productrepository in ReInitializeTest() method and SetUpTokenRepository() to mock TokenRepository and assign that to _tokenRepository in ReInitializeTest() method.
SetUpProductRepository()
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;
}
SetUpTokenRepository()
private GenericRepository<Token> SetUpTokenRepository()
{
// Initialise repository
var mockRepo = new Mock<GenericRepository<Token>>(MockBehavior.Default, _dbEntities);
// Setup mocking behavior
mockRepo.Setup(p => p.GetAll()).Returns(_tokens);
mockRepo.Setup(p => p.GetByID(It.IsAny<int>()))
.Returns(new Func<int, Token>(
id => _tokens.Find(p => p.TokenId.Equals(id))));
mockRepo.Setup(p => p.Insert((It.IsAny<Token>())))
.Callback(new Action<Token>(newToken =>
{
dynamic maxTokenID = _tokens.Last().TokenId;
dynamic nextTokenID = maxTokenID + 1;
newToken.TokenId = nextTokenID;
_tokens.Add(newToken);
}));
mockRepo.Setup(p => p.Update(It.IsAny<Token>()))
.Callback(new Action<Token>(token =>
{
var oldToken = _tokens.Find(a => a.TokenId == token.TokenId);
oldToken = token;
}));
mockRepo.Setup(p => p.Delete(It.IsAny<Token>()))
.Callback(new Action<Token>(prod =>
{
var tokenToRemove =
_tokens.Find(a => a.TokenId == prod.TokenId);
if (tokenToRemove != null)
_tokens.Remove(tokenToRemove);
}));
// Return mock implementation object
return mockRepo.Object;
}
Unit Tests

All is set now, and we are ready to write unit tests for ProductController. We’ll write a test to perform all the CRUD operations and all the action exit points that are part of ProductController.
GetAllProductsTest ()
Our ProductService in BusinessServices project contains a method named GetAllProducts (), following is the implementation.
[Test]
public void GetAllProductsTest()
{
var productController = new ProductController(_productService)
{
Request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri(ServiceBaseURL + "v1/Products/Product/all")
}
};
productController.Request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, new HttpConfiguration());
_response = productController.Get();
var responseResult = JsonConvert.DeserializeObject<List<Product>>(_response.Content.ReadAsStringAsync().Result);
Assert.AreEqual(_response.StatusCode, HttpStatusCode.OK);
Assert.AreEqual(responseResult.Any(), true);
var comparer = new ProductComparer();
CollectionAssert.AreEqual(
responseResult.OrderBy(product => product, comparer),
_products.OrderBy(product => product, comparer), comparer);
}
Let me explain the code step by step. We start the code by creating an instance of ProductController and initialize the Request property of the controller with a new request message stating calling HTTP method as GET and initialize the RequestUri with base hosted service URL and append with the actual endpoint of the method. Initializing RequestUri is not necessary in this case but will help you if you test the actual service endpoint. In this case, we are not testing the actual endpoint but the direct controller method.
HttpPropertyKeys.HttpConfigurationKey, newHttpConfiguration() line adds default HTTP configuration to HttpConfigurationKey necessary for controller instance instantiation.
_response = productController.Get(); line calls the Get() method of the controller that fetches all the products from the dummy _products list. Since the return type of the method was an HTTP response message, we need to parse it to get the JSON result sent from the method. All the transactions from APIs should ideally happen in the form of JSON or XML only. This helps the client to understand the response and its result set. We de-serialize the object we got from _response using the NewtonSoft library into a list of products. That means the JSON response is converted to List<Product> for better accessibility and comparison. Once done with JSON to List object conversion, I have put three asserts to test the result.
Assert.AreEqual(_response.StatusCode, HttpStatusCode.OK); line checks the HTTP status code of the response, the expected is HttpStatusCode.OK.
Second assert i.e. Assert.AreEqual(responseResult.Any(), true); checks that we have got the items in the list or not. The third assert is the actual confirmation assert for our test that compares each product from the actual product list to the returned product list.

We got both the list, and we need to check the comparison of the lists, I just pressed F5 and got the result on TestUI as.

This shows our test is passed, i.e. the expected and returned result is the same.
GetProductByIdTest()
This unit test verifies if the correct result is returned if we try to invoke the GetProductById() method of the product controller.






















svr technologiesPosted Apr 30, 2018, 6:29 AM
Great explanation! Enjoyed and learnt a lot thru the series. When can we expect the Day 9 Tutorial.
kiquenet kiquenetPosted Feb 21, 2018, 10:26 AM
Great! How can I do Integration test to call to external REST Services (another client company, not mine) using OAuth authentication ?
Former memberPosted Mar 17, 2017, 4:41 AM
Sir- How to define what is REST in simple way with a example. please give me easy explanation.
Aakash GPosted Mar 15, 2017, 11:27 AM
Great explanation! Enjoyed and learnt a lot thru the series. When can we expect the Day 9 Tutorial,
Debasis SahaPosted Mar 31, 2016, 1:08 AM
Good One..
Jaipal ReddyPosted Mar 30, 2016, 12:26 AM
Nice
Imtiyaz AnsariPosted Mar 29, 2016, 10:26 AM
Nice Describe all points...
Vipul MalhotraPosted Mar 29, 2016, 7:38 AM
nice
Abhishek KumarPosted Mar 9, 2016, 8:25 AM
nice article..
Shailesh UkePosted Mar 9, 2016, 1:05 AM
Nice One..
Ravi PatelPosted Mar 8, 2016, 4:04 AM
sir, thanks for great article
Raja TPosted Mar 8, 2016, 3:02 AM
Nice,Thanks for sharing
Saillesh PawarPosted Mar 7, 2016, 11:02 PM
Great job Akhil sir. Your article has been helpful in implementing many web api requirement in my project. Appreciate your hardwork. Have to read full series.
Asfend YarPosted Mar 7, 2016, 12:04 PM
nice
Sibeesh VenuPosted Mar 7, 2016, 7:23 AM
Nice read
Vignesh ManiPosted Mar 7, 2016, 6:05 AM
Good
Mohammed IbrahimPosted Mar 7, 2016, 4:09 AM
nice