DEV Community

Sharath
Sharath

Posted on • Updated on

Mocking HttpClients using HttpClientHandler in C#

I was working on a gateway which based on the logged-in user would call APIs in the appropriate system appropriately. The architecture was basically client would call an API in the gateway and the gateway would in effect then redirect the call to the appropriate backend system as shown below.
Architecture

The gateway directly calls APIs of the 2 source systems using HttpClient. The HttpClient had to be mocked to write UnitTests and the HttpClientHandler class was used to override the SendAsync method to return appropriate statuses based on the tests.
A Sample implementation is as shown below

In the below code snippet the method TestForHttpClient has to be tested and here we need to mock the implementation of httpClient.GetAsync(Uri url) method.

public class ClassForUT
    {
        private HttpClient _httpClient;

        public ClassForUT(HttpClient httpClient)
        {
            _httpClient = httpClient;
        }
        public async Task<HttpResponseMessage> TestForHttpClients()
        {
            var content = await _httpClient.GetAsync("http://www.google.com");
            return content;
        }
    }

Solution:

A Mock class was created which inherited from the HttpClientHandler class. HttpClients were created which were an object of this mocked class. The _GetAsync _ method of the HttpClient was abstracted in this class.

public abstract class MockHttpHandler : HttpClientHandler
    {
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken token)
        {
            var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
            return await Task.FromResult(response);
        }

        public abstract HttpResponseMessage GetAsync(Uri url);
    }

Then the test method is created as shown below

 public class ClassForUTTests : IDisposable
    {
        private HttpClient _mockClient;
        private Mock<MockHttpHandler> _mockHttpClient;

 public ClassForUTTests()
        {
            _mockHttpClient = new Mock<MockHttpHandler> { CallBase = true };
            _mockClient = new HttpClient(_mockHttpClient.Object);
        }

[Fact(DisplayName ="Test For HttpClients Test")]
        public async void HttpClientsTest()
        {
            ClassForUT utClass = new ClassForUT(_mockClient);
            _mockHttpClient.Setup(p=>p.GetAsync(It.IsAny<Uri>()));
            var result = await utClass.TestForHttpClients();
            Assert.Equal(System.Net.HttpStatusCode.OK, result.StatusCode);
        }

        public void Dispose()
        {
            _mockClient=null;
            _mockHttpClient=null;
        }

}

Here when the GetAsync method is called, the GetAsync method from the MockHttpHandler class gets invoked which returned the response from the overridden SendAsync method.

Top comments (0)