The cost of fixing bugs is lower if found early in the software development cycle. Unit tests greatly reduce this cost by pushing quality upstream. This helps prevent regression bugs and when coupled with TDD approach, provides a solid foundation for a complete test suite. Furthermore, teams are striving to push code into production more frequently and with higher quality. In order to flourish in this DevOps space, it is imperative to have a pipeline of solid automated tests. Traditionally, unit tests have been written for a class library projects or middle tier/business logic projects.
In this blog post, I will demonstrate how to easily unit test an OData based Web API service which is consuming data from SQL DB using Entity Framework. The goal is to write unit tests which stub out the actual DB calls. We will make use of faking the DB Context and using a common DI pattern of construction injection. The result is a highly testable maintainable and cohesive codebase.
Create the ASP.NET Web Application
First, open Visual Studio VS 2013, create an ASP.Net Web Application, choose MVC and Web API template and check the Add Unit Tests checkbox.
Create the DB
Next, create a SQL Database as the backend for this project. Use SQL Server Edition of your choice. I am using SQL Server 2014 for this post. We will use Entity Framework(EF 22.214.171.124) to connect to this DB.
Let the DB name be ODataDB
Next up, create a Table in the database named Application with following properties.
Create the Application Table
Reverse Engineer Code First from the DB
Right Click on the Web API project we created to reverse engineer code from the database. You will need to install Visual Studio Entity framework extensions.
Make sure Entity Framework dll’s are referenced in the project.
We now have Application Map.cs and ODataDBContext.cs created and mapping created.
Next up, install Web API OData Libraries from Nuget for the Web API project. I am using the latest version of ASP.Net Web API2.2 for OData v1-3
Now let’s create ODataController based on Entity Framework and call it Application Controller.
We will use ApplicationMap and ODataDBContext for Model and Data Context class respectively.
Now that Application Controller is created and we have our Get/Post/Put operations in place in the controller class.
Click F5, and the OData Service is up and running!
Create Unit Test for the Application Controller
Now that the application is running, we want to write unit tests for it.
First and foremost, we need to Fake Out the DB Context in our application. Instead of using the ODataDBContext, we will use FakeDBContext. In order to do that we first need to create an interface for ODataDBContext. We will call it IODataDBContext and have ODataDBContext implement from it.
Create Interface IODataDBContext
Implement IODataDBContext from ODataDBContext
Run the application to see everything works like before. Now that the IODataDBContext is in place, let’s create FakeDBContext in the Unit Test Project.
Unit Test Project Plumbing
Add the following to the Unit Test Project.
- Add FakeODataDBContext to the unit test project. Ensure that FakeODataDBContext implements the IODataDBContext Interface.
- Add Entity framework dll to the references.
- Add System.Web.Http dll to the references.
- Add System.Web.Http.OData dll to the references.
- Add FakeDBSet class to the project.
Notice the constructor in the FakeODateDBContext, it has a method called GetApp(), this method is used to create the Fake Application object which is returned to the Unit test when calling the ODataController for Application.
Below is the code for GetApp(), Here we are using the FakeDbSet to create a Fake Application Object in memory for the purposes of the Unit Test.
Before we start writing Unit Tests, we need to tweak the controller code to expose the ODataDBContext object as a parameter. This is classic case of constructor dependency injection which would make the code testable.
Now, let’s write the Unit Test for the Application Controller. Here is the Code for the unit test. The unit test is a Visual Studio Unit Test.
As you see above, we have successfully written a Unit Test for the ODataController Api. The above unit test will exercise the code paths of your controller code and also execute any logic inside it without having to make the actual Database call. The FakeDBContext lets you get/set data in memory and disposes it once the unit test exits.
You can potentially create Unit Tests for all your Controller methods(Get,Post.Put,Delete) across all your application and ensure very high Code Coverage and a highly testable and maintainable application.
Hopefully this post helps you start writing Unit tests for ODataController Services using Entity Framework.