/NUnit

Mocking HttpClient for unit testing

Introduction

HttpClient is an easy way provided by dotnet to send http requests. But the problem is that it doesn’t implement an interface we could mock for unit testing.

How to mock HttpClient

Say we have a function GetResponse like below:

public async Task<string?> GetResponse(HttpClient httpClient, string requestUri)
{
        var request = new HttpRequestMessage
        {
            Method = HttpMethod.Get,
            RequestUri = new Uri(requestUri)
        };

        using var response = await httpClient.SendAsync(request);
        response.EnsureSuccessStatusCode();
        string? responseBody = await response.Content.ReadAsStringAsync();
        return responseBody;
}

Moq for mocking

Let’s use Moq for mocking. If you notice the method we would like to stub is SendAsync, which is a protected method in HttpClient class. The way to mock that is:

public static HttpClient GetMockedHttpClient(string responseContent)
{
    var handlerMock = new Mock<HttpMessageHandler>();
    var response = new HttpResponseMessage
    {
        StatusCode = HttpStatusCode.OK,
        Content = new StringContent(responseContent),
    };

    handlerMock
        .Protected()
        .Setup<Task<HttpResponseMessage>>(
            "SendAsync",
            ItExpr.IsAny<HttpRequestMessage>(),
            ItExpr.IsAny<CancellationToken>())
        .ReturnsAsync(response);
    var httpClient = new HttpClient(handlerMock.Object);
    return httpClient;
}

Notice how the SendAsync method has now been stubbed and this can be used in unit tests.

So in a unit test we can call GetResponse as follows:

var mockedHttpClient = GetMockedHttpClient("{}");
var response = someObject.GetResponse(mockedHttpClient, "some-uri");

Conclusion

Hope this was useful and saves you some time if you are trying this out. If you have any thoughts or comments please do get in touch with me on Twitter @rubberduckdev. Or use the Disqus plugin below.

Dushyant

Dushyant

Check about page for details.

Read More

Mocking HttpClient for unit testing

...