Unit Testing a Method That Uses HttpClient

Full source code available here.

In this post I’m going to show you how test an action method of controller that uses a HttpClient. When performing this test you want to isolate just the code of the action method for testing, you want to remove the dependency on the HttpClient. I hoped it would be simple, that there would be an IHttpClient, but there is not.

Instead I mocked the HttpMessageHandler, then pass it to the constructor of the HttpClient. The HttpMessageHandler is set to return a list of numbers in response to any request.

The constructor of the controller takes the HttpClient as a parameter, usually passed by dependency injection.

public class ValuesController : Controller
    readonly IAsyncPolicy<HttpResponseMessage> _httpRetryPolicy;
    private readonly HttpClient _httpClient;

    public ValuesController(HttpClient httpClient)
        _httpClient = httpClient;

In the test class I mock the HttpMessageHandler, set its SendAsync method to return OK and a list of numbers in response to any request. I then pass the mocked HttpMessageHandler to the constructor of the HttpClient.

Now the HttpClient will return the list of numbers I expect and I my test just tests the code of the action method.

The rest of the test is written as normal.

public async Task GetTest()
    string numberJson= JsonConvert.SerializeObject(new List<int>() { 1, 2, 3, 4, 5 });

    var httpMessageHandler = new Mock<HttpMessageHandler>();
        .Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(),
        .Returns(Task.FromResult(new HttpResponseMessage
            StatusCode = HttpStatusCode.OK,
            Content = new StringContent(numberJson, Encoding.UTF8, "application/json"),

    HttpClient httpClient = new HttpClient(httpMessageHandler.Object);
    httpClient.BaseAddress = new Uri(@"http://localhost:63781/v1/");
    httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    ValuesController controller = new ValuesController(httpClient);

    IActionResult result = await controller.Get();

    OkObjectResult resultObject = result as OkObjectResult;

    List<int> numbers = resultObject.Value as List<int>;
    Assert.Equal(5, numbers.Count);

Full source code available here.

Reusing HttpClient with Dependency Injection

Full source code available here.

If you are using HttpClient to make requests for you, you might have come across some articles discussing how to reuse HttpClient. They strongly advocate for using a single HttpClient for as many requests as possible, i.e. not creating a new HttpClient for every request.
Not having to create/dispose of the HttpClient for every request should improve the performance of you application. One estimate states that every time you instantiate a HttpClient takes 35ms.

In this article I will show you how to use dependency injection to reuse the HttpClient in .Net Core, but the same principle applies in Framework 4.x applications.

The one advantage of creating a new HttpClient for every request is that you don’t need to worry about the DNS record of an endpoint changing during the lifetime of the application, this is common if you are swapping staging and production instances during a deployment. But this is easyly(ish) handled by the ServicePointManger.

Adding HttpClient to the DI Container
In Startup.cs add the below lines.

public void ConfigureServices(IServiceCollection services)
    Uri endPointA = new Uri("http://localhost:58919/"); // this is the endpoint HttpClient will hit
    HttpClient httpClient = new HttpClient()
        BaseAddress = endPointA,

    ServicePointManager.FindServicePoint(endPointA).ConnectionLeaseTimeout = 60000; // sixty seconds

    services.AddSingleton<HttpClient>(httpClient); // note the singleton

This approach is ideal if you have a limited number of endpoints and you know them at application startup. If you don’t know then endpoints at startup you can add the call to ServicePointManager where you HttpClient requests occur.

Using the HttpClient
Now I have the HttpClient registered with the Dependency Injection container, let’s take a look at the controller that uses it to make a request. See the inline comments.

public class ValuesController : Controller
    private readonly HttpClient _httpClient; // declare a HttpClient

    public ValuesController(HttpClient httpClient) // this is the singelton instance of HttpClient
        _httpClient = httpClient; // assign it to the local HttpClient

    // GET api/values
    public async Task<IActionResult> Get()
        string requestEndpoint = "api/products";

        HttpResponseMessage httpResponse = await _httpClient.GetAsync(requestEndpoint); // make request
        List<Product> products = await httpResponse.Content.ReasAsJsonAsync<List<Product>>();
        return Ok(products);

Full source code available here.

Web API 2 and ninject, how to make them work together

Full source code to download.

I’ve been using ninject for a few years, but every time I use it with Web Api I hit some problem and they usually stem from not including the right nuget packages, not changing the DependencyResolver or (once) forgetting how to make a binding!

For my future self and your reference, here is how it is done.

1. Nuget packages

Add Ninject.Web.WebApi using nuget to your Web Api project.

That will install two other package dependencies:

To make everything work you need to add one more nuget package

This will pull down the WebActivatorEx package and add a new class called NinjectWebCommon to your App_Start directory.

2. Edit NinjectWebCommon.cs

NinjectWebCommon.cs is missing a key feature if you want to use ninject to construct the controllers, and I presume that is why you are using ninject inside a Web Api project.

In the CreateKernel() method add the second line shown below. Now ninject will be used to resolve controller dependencies.

GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
return kernel;

You will need to add a couple of using statements too –

using System.Web.Http;
using Ninject.Web.WebApi;

3. Register some services

To actually register some services we move to the RegisterServices(..) method do some binding.

private static void RegisterServices(IKernel kernel)

4. Use it all

And here is the usage in the controller.

    public class ValuesController : ApiController
        private readonly ICaclulator _caclulator;
        public ValuesController(ICaclulator calculator)
            _caclulator = calculator;

        public int Get(int num1, int num2)
            return _caclulator.Add(num1, num2);

Full source code to download.

CastleWindsor chained dependency

Source code is available here.

I recently had a problem where I wanted an MVC controller to use constructor injection of specified dependency and have that dependency load another specified dependency using Windsor.

For example, I have a message of the day controller and it can get messages from either a file or from a database. To support this I have a message of the day service which formats the text it retrieves from a message of the day loader.

But as I said I have two ways of loading the message, so for the sake of this demo I have two services and two loaders.

Controller, service and loader dependencies

Controller, service and loader dependencies

I don’t want my controller to request a named instance, I just want to register the implementations in the installers and let Windsor do the rest.

If the controller is using the database service, I want the database service to use the database loader; if the controller is using the file service, I want the file service to use the file loader.

To support this I added a ContractInstaller as shown here.

    public class ContractInstaller : IWindsorInstaller
        public void Install(IWindsorContainer container, IConfigurationStore store)

                    .DependsOn(Dependency.OnComponent<IMessageLoader, MessageLoaderDatabase>())

                    .DependsOn(Dependency.OnComponent<IMessageLoader, MessageLoaderFile>())

                    .DependsOn(Dependency.OnComponent<IMessageOfTheDayService, MessageOfTheDayServiceFile>())

In lines 6 and 7 I register the loaders (IMessageLoader), and in lines 9 and 12 I register the the services (IMessageOfTheDayService) and they in turn depend on the registered loaders.
In line 15 I register the controller (MessageOfTheDayController) and its dependency on IMessageOfTheDayService, in this case it is using MessageOfTheDayServiceFile.
To use the MessageOfTheDayServiceDatabase, change the dependency on line 16.

Be sure to load this before the ControllersInstaller provided by the Windsor nuget or you will get a clash between the MessageOfTheDayController loaded by both installers. To make sure this happens I alter the default Bootstrap method in ContainerBootstrapper to the following.

        public static ContainerBootstrapper Bootstrap()
            var container = new WindsorContainer().Install(
                new ContractInstaller(),
                new ControllersInstaller()

            return new ContainerBootstrapper(container);

Now when you run the app, the controller will be instantiated with the MessageOfTheDayServiceDatabase which in turn will be instantiated with MessageLoaderDatabase.