Quantcast
Channel: Code – no dogma blog
Viewing all articles
Browse latest Browse all 132

Unit Testing a Method That Uses HttpClient

$
0
0

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;
    }
	//snip..

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.

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

    var httpMessageHandler = new Mock<HttpMessageHandler>();
    httpMessageHandler.Protected()
        .Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(),
            ItExpr.IsAny<CancellationToken>())
        .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.Clear();
    httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    ValuesController controller = new ValuesController(httpClient);

    //Act
    IActionResult result = await controller.Get();

    //Assert
    OkObjectResult resultObject = result as OkObjectResult;
    Assert.NotNull(resultObject);

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

Full source code available here.


Viewing all articles
Browse latest Browse all 132

Trending Articles