I don't understand what you mean with
http typed client
but if like in the example, you want to test a class which uses HttpClient, either you create a wrapper for HttpClient and pass it's interface using dependency injection (so you can mock it), or you leverage the HttpResponseMessage constructor parameter of the HttpClient.
Make the HttpClient a constructor parameter and in the test create code like the following:
var mockHttpMessageHandler = new Mock<HttpMessageHandler>();
mockHttpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.IsAny<HttpRequestMessage>(), // Customise this as you want
ItExpr.IsAny<CancellationToken>()
)
// Create the response you want to return
.ReturnsAsync(new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent("[{'prop1': 100,'prop2': 'value'}]"),
});
// Create an HttpClient using the mocked message handler
var httpClient = new HttpClient(mockHttpMessageHandler.Object)
{
BaseAddress = new Uri("http://anyurl.com/"),
};
var testedService = new MyServiceUnderTest(httpClient);
var result = await testedService.MethodUnderTest(parameters [...]);
To simplify the setup of the moq, restricting the expected HttpRequestMessage, I use this helper method.
/// <summary>
/// Setup the mocked http handler with the specified criteria
/// </summary>
/// <param name="httpStatusCode">Desired status code returned in the response</param>
/// <param name="jsonResponse">Desired Json response</param>
/// <param name="httpMethod">Post, Get, Put ...</param>
/// <param name="uriSelector">Function used to filter the uri for which the setup must be applied</param>
/// <param name="bodySelector">Function used to filter the body of the requests for which the setup must be applied</param>
private void SetupHttpMock(HttpStatusCode httpStatusCode, string jsonResponse, HttpMethod httpMethod, Func<string, bool> uriSelector, Func<string, bool> bodySelector = null)
{
if (uriSelector == null) uriSelector = (s) => true;
if (bodySelector == null) bodySelector = (s) => true;
_messageHandlerMock
.Protected()
.Setup<Task<HttpResponseMessage>>("SendAsync",
ItExpr.Is<HttpRequestMessage>(m =>
m.Method == httpMethod &&
bodySelector(m.Content.ReadAsStringAsync().Result) &&
uriSelector(m.RequestUri.ToString())),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(new HttpResponseMessage
{
StatusCode = httpStatusCode,
Content = jsonResponse == null ? null : new StringContent(jsonResponse, Encoding.UTF8, "application/json")
});
}