For the sake of simplicity lets suppose that your to be tested method looks like this:
public class ToBeTestedClass
{
private readonly HttpClient client;
public ToBeTestedClass(HttpClient client)
=> this.client = client;
public HttpResponseMessage ToBeTestedMethod()
{
HttpRequestMessage request = new(HttpMethod.Get, "https://httpstat.us/200");
return client.Send(request);
}
}
As it was mentioned by Kalten you can mock the underlying HttpMessageHandler
to test the HttpClient
. In the linked thread the solution used SendAsync
but it can be easily adjusted to use Send
instead.
public void GivenAFlawlessHttpClient_WhenICallToBeTestedMethod_ThenItInvokesTheHttpClientsSend()
{
//Arrange
const string SendMethodName = "Send";
var handlerMock = new Mock<HttpMessageHandler>();
handlerMock.Protected()
.Setup<HttpResponseMessage>(
SendMethodName,
ItExpr.IsAny<HttpRequestMessage>(),
ItExpr.IsAny<CancellationToken>())
.Returns(new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent("Dummy response")
});
//Act
var testedClass = new ToBeTestedClass(new HttpClient(handlerMock.Object));
var response = testedClass.ToBeTestedMethod();
//Assert
handlerMock.Protected().Verify(
SendMethodName,
Times.Once(),
ItExpr.Is<HttpRequestMessage>(req =>
req.Method == HttpMethod.Get
&& req.RequestUri == new Uri("https://httpstat.us/200")
),
ItExpr.IsAny<CancellationToken>()
);
}
Please note that you should youse ItExpr
instead of It
otherwise you will get an ArgumentException
.