DEV Community

Sharath
Sharath

Posted on • Edited on

1

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.

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay