Home > Blockchain >  How to make httpclient mock method generic for json serialization
How to make httpclient mock method generic for json serialization

Time:04-27

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;
}
  • Related