Unable to Mock HttpClient PostAsync() in unit tests

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:

// Act
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:

  1. Unit Testing with the HttpClient
  2. How to mock HttpClient in your .NET / C# unit tests

Leave a Comment