Unit Test for Methods that Call Web API

HttpClient helps you interact with your Rest API’s through its asynchronous methods such as GetAsync. But on a TDD environment, it could become a challenge on how you could write Unit Test cases for a method that invokes the API via GetAsync and ensure that your call successfully invokes the API (considering your API sits in another server and calling it your unit tests would not be ideal). The way I approached this by creating a self hosted API within the Unit Test Project and make the Test Method calls to the API.

The first step was to use Open Web Interface for .Net (or OWIN) to self host an API. Microsoft has put on an extremely useful link for the purpose. Following become by code to configure the API.

 public class WebApiStartup
 {
 // This code configures Web API. The Startup class is specified as a type
 // parameter in the WebApp.Start method.
 public void Configuration(IAppBuilder appBuilder)
 {
 // Configure Web API for self-host. 
 HttpConfiguration config = new HttpConfiguration();
 config.Routes.MapHttpRoute(
 name: "DefaultApi",
 routeTemplate: "api/{controller}/{id}",
 defaults: new { id = RouteParameter.Optional }
 );

 appBuilder.UseWebApi(config);
 }
 }
 The Next Step is go ahead and create the Test Controller, which would be hosting all your api methods.
 [RoutePrefix("api/user")]
public class UserController : ApiController
{
[HttpGet]
[Route("")]
public bool NoParamBooleanResponse()
{
return true;
}
}

Finally, its time to go ahead and write the Test Methods.

 private const string _BaseAddress = "http://localhost:9388/";

[TestMethod]
public async Task CallNoParamAPI_ServerRunning_GetResponseTrue()
{

#region Arrange

var resourceURL = "api/user/SingleParamBooleanResponse";
var restHelper = new RestHelper(_BaseAddress);
bool result;
#endregion

#region Act
using (WebApp.Start<WebApiStartup>(_BaseAddress))
{
result = await restHelper.ExecuteAsync<bool>(resourceURL,HttpMethod.Get);
}
#endregion

#region Assert
Assert.IsTrue(result);
#endregion

}

In the above example, my  restHelper.ExecuteAsync() method invokes the GetAsync Method of HttpClient.

Mocking IDispossible with “Using”

Mocking objects is integral part of Unit Testing. The nucleus of Mocking is Dependency Injection, which allows us to inject Mock object into the code. But what happens when programmer has used the “Using” keyword ? For Example,

using(CustomDbCommand cmd = new CustomDbCommand ())
{
// Code
}
<pre>

This makes it difficult to mock DbCommand. The solution lies in deploying Factory Pattern to create our CustomDbCommand. For the purpose, I have created a IDbCommandFactory interface and its concrete solution in DbCommandFactory. It comprises of a method called CreateDbCommandObject, which returns a new instance of CustomDbCommand;

public interface IDbCommandFactory
{
CustomDbCommand CreateDbCommandObject();
}

public class DbCommandFactory : IDbCommandFactory
{
public CustomDbCommand CreateDbCommandObject()
{
return new CustomDbCommand();
}
}

Now that we have our Factory Object ready, it is time to inject it into our Repository Class. I prefer to use Constructor Injection for the purpose.


private readonly IDbCommandFactory objDbCommmandFactory;
public TestRepository( IDbCommandFactory DbCommandFactory)
{
objDbCommmandFactory = DbCommandFactory;
}

public void TestMethod()
{
using ( var cmd = objDbCommmandFactory.CreateDbCommandObject())
{
// Code
}
}

Now we are all set to Mock our CustomDbCommand Object, or in other words, our IDispossible object. Happy Unit Testing.