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.