Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mock HttpClient using Moq

I would like to unit test a class that uses HttpClient. We injected the HttpClient object in the class constructor.

public class ClassA : IClassA
{
    private readonly HttpClient _httpClient;

    public ClassA(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }

    public async Task<HttpResponseMessage> SendRequest(SomeObject someObject)
    {
        //Do some stuff

        var request = new HttpRequestMessage(HttpMethod.Post, "http://some-domain.in");

        //Build the request

        var response = await _httpClient.SendAsync(request);

        return response;
    }
}

Now we would like to unit test the ClassA.SendRequest method. We are using Ms Test for unit testing framework and Moq for mocking.

When we tried to mock the HttpClient, it throws NotSupportedException.

[TestMethod]
public async Task SendRequestAsync_Test()
{
    var mockHttpClient = new Mock<HttpClient>();

    mockHttpClient.Setup(
        m => m.SendAsync(It.IsAny<HttpRequestMessage>()))
    .Returns(() => Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK)));
}

How can we solve this issue?

like image 830
Amitava Karan Avatar asked Jun 23 '17 07:06

Amitava Karan


1 Answers

Moq can Mock out protected methods, such as SendAsync on the HttpMessageHandler that you can provide to HttpClient in its constructor.

var mockHttpMessageHandler = new Mock<HttpMessageHandler>();
mockHttpMessageHandler.Protected()
    .Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
    .ReturnsAsync(new HttpResponseMessage
    {
        StatusCode = HttpStatusCode.OK
     });

var client = new HttpClient(mockHttpMessageHandler.Object);

Copied from https://thecodebuzz.com/unit-test-mock-httpclientfactory-moq-net-core/

like image 144
carlin.scott Avatar answered Oct 02 '22 00:10

carlin.scott