skip to Main Content

I am very new to Testing. I am trying to understand how can I unit test since I do not really need to actually trigger these services but probably mock every step.

How can I unit test the following piece of code?

public void myFunction()
{
// I am getting an auth token from a service
// then 

    using (HttpClient httpClient = new HttpClient())
    {
    // do a POST call on another service
    var response = httpClient.PostAsync(url, content);
    }

}

2

Answers


  1. Non-overridable members (here: HttpClient.PostAsync) may not be used in setup / verification expressions.

    I also tried to mock the HttpClient the same way you did, and I got the same error message.

    Non-overridable members (here: HttpClient.PostAsync) may not be used in setup / verification expressions.

    I also tried to mock the HttpClient the same way you did, and I got the same error message.

    Solution:
    Instead of mocking the HttpClient, mock the HttpMessageHandler.

    Then give the

    mockHttpMessageHandler.Object

    to your HttpClient, which you then pass to your product code class. This works because HttpClient uses HttpMessageHandler under the hood:

    // Arrange
    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);
    this._iADLS_Operations = new ADLS_Operations(client);
    

    Note: You will also need a

    using Moq.Protected;
    

    at the top of your test file.

    Then you can call your method that uses PostAsync from your test, and PostAsync will return an HTTP status OK response:

    var returnedItem = this._iADLS_Operations.MethodThatUsesPostAsync(/*parameter(s) here*/);
    

    Advantage: Mocking HttpMessageHandler means that you don’t need extra classes in your product code or your test code.

    Helpful resources:


    https://chrissainty.com/unit-testing-with-httpclient/


    https://gingter.org/2018/07/26/how-to-mock-httpclient-in-your-net-c-unit-tests/

    Login or Signup to reply.
  2. After mock arrangements can be verify with

    mockHttpMessageHandler.Protected().Verify("SendAsync", Times.Once(), ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>());
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search