Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create mock for httpclient getasync method?

I am using Moq to create mocks for my unit tests but I am stuck when I have to create mock for getasync method of httpclient. Previously I was using SendAsync method and for that I could use the below code:

   var mockResponse =
            new HttpResponseMessage(HttpStatusCode.OK) {Content = new StringContent(expectedResponse)};
        mockResponse.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
        var mockHandler = new Mock<DelegatingHandler>();
        mockHandler
            .Protected()
            .Setup<Task<HttpResponseMessage>>(
                "SendAsync",
                ItExpr.Is<HttpRequestMessage>(
                    message => message.Headers.Contains("Authorization")
                               && message.Headers.Authorization.Parameter.Equals(accessToken)
                               && message.Headers.Authorization.Scheme.Equals("Bearer")
                               && message.RequestUri.AbsoluteUri.Contains(baseUrl)
                ),
                ItExpr.IsAny<CancellationToken>())
            .Returns(Task.FromResult(mockResponse));

Now I have a method:

  private async Task<List<Model>> GetData()
  {
        string url = url;
        _httpClient.BaseAddress = new Uri(url);
        _httpClient.DefaultRequestHeaders.Add(Headers.AuthorizationHeader, "Bearer" + "token");
        var response = await _httpClient.GetAsync(url);
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadAsAsync<List<Model>>();
  }

Now can I create mock for this method (getasync)? Any help?

like image 201
Ask Avatar asked Oct 31 '18 10:10

Ask


People also ask

Can I mock HttpClient?

HttpClient's extensibility lies in the HttpMessageHandler passed to the constructor. Its intent is to allow platform specific implementations, but you can also mock it. There's no need to create a decorator wrapper for HttpClient.

How do you mock HttpRequestMessage?

Returns("my_ticket"); Mock<HttpRequestMessage> req = new Mock<HttpRequestMessage>(); req. Setup(m => m. CreateResponse( HttpStatusCode. OK, "value")) .

What is HttpClient GetAsync?

GetAsync(String, HttpCompletionOption) Send a GET request to the specified Uri with an HTTP completion option as an asynchronous operation. GetAsync(String, CancellationToken) Send a GET request to the specified Uri with a cancellation token as an asynchronous operation.

What does HttpClient GetAsync return?

The HTTP request is sent out, and HttpClient. GetAsync returns an uncompleted Task .

Is there a way to mock a httpclient?

Your best alternative would be to create a Adapter/wrapper for HttpClient and mock that in this case. Something like

How do I mock HTTP requests in Moq?

With the help of extension methods, mocking HTTP requests can be just as easy as mocking a service method. HttpClient with vanilla Moq HttpClient itself is merely a set of helpers wrapping an HttpMessageHandler; all requests ultimately go through the handler’s sole SendAsync method.

How to demonstrate httpclient mocking using xUnit?

To demonstrate httpclient mocking using Xunit, I am creating a simple web API application and adding a new test (XUnit) project. Let's introduce IHttpClientHelper interface to mock httpclient. Here you can see HttpClient property as well, which is used to hold the mocked HttpMessageHandler object.

How do I mock a call to the sendasync() function?

We mock a call to the SendAsync () function and provide a response to return with the ReturnAsync () method. In the Setup<> () method, the first parameter is the name of the method that is being mocked. Next, we match each parameter to the "SendAsync" method with an expression.


1 Answers

Internally GetAsync will eventually call SendAsync.

public Task<HttpResponseMessage> GetAsync(Uri requestUri, HttpCompletionOption completionOption,
    CancellationToken cancellationToken)
{
    return SendAsync(new HttpRequestMessage(HttpMethod.Get, requestUri), completionOption, cancellationToken);
}

Source code

Loosen the ItExpr expectation and you should be able to get it to behave as expected.

Using the originally provided example

mockHandler
    .Protected()
    .Setup<Task<HttpResponseMessage>>(
        "SendAsync",
        ItExpr.IsAny<HttpRequestMessage>(),
        ItExpr.IsAny<CancellationToken>()
    )
    .ReturnsAsync(mockResponse);
like image 160
Nkosi Avatar answered Nov 14 '22 22:11

Nkosi