I have the following private method allows me to Mock and therfore test a HttpClient
private Mock<HttpClient> GetMockHttClient(HttpStatusCode desiredStatusCode, User user)
{
var httpMessageHandler = new Mock<HttpMessageHandler>();
httpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.IsAny<HttpRequestMessage>(),
ItExpr.IsAny<CancellationToken>()
)
.ReturnsAsync((HttpRequestMessage request, CancellationToken token) =>
{
var response = new HttpResponseMessage
{
Content = new StringContent(JsonSerializer.Serialize(user)), //<-- this could be anything
ReasonPhrase = null,
RequestMessage = null,
StatusCode = desiredStatusCode,
Version = new Version(1, 0)
};
return response;
});
var httpClientMock = new Mock<HttpClient>(httpMessageHandler.Object)
{
Object =
{
BaseAddress = new Uri("[Redacted]")
}
};
return httpClientMock;
}
For now I am passing in a User object, however I have other tests where I might for example want an int[]
serializing, or a List<User>
serializing.
It seems ridiculous to copy and paste this method and change the object I wish to serialize, so how can I make this method generic so that when I call it, I can specify the type that will be serialized to json.
CodePudding user response:
private Mock<HttpClient> GetMockHttClient<TModel>(HttpStatusCode desiredStatusCode, TModel model)
{
var httpMessageHandler = new Mock<HttpMessageHandler>();
httpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.IsAny<HttpRequestMessage>(),
ItExpr.IsAny<CancellationToken>()
)
.ReturnsAsync((HttpRequestMessage request, CancellationToken token) =>
{
var response = new HttpResponseMessage
{
Content = new StringContent(JsonSerializer.Serialize<TModel>(model)),
ReasonPhrase = null,
RequestMessage = null,
StatusCode = desiredStatusCode,
Version = new Version(1, 0)
};
return response;
});
var httpClientMock = new Mock<HttpClient>(httpMessageHandler.Object)
{
Object =
{
BaseAddress = new Uri("[Redacted]")
}
};
return httpClientMock;
}