Reputation: 63
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);
}
}
Upvotes: 0
Views: 4065
Reputation: 109
After mock arrangements can be verify with
mockHttpMessageHandler.Protected().Verify("SendAsync", Times.Once(), ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>());
Upvotes: 1
Reputation: 145
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/
Upvotes: 2