Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock a Stream response when calling HttpClient GetStreamAsync

I'm trying to test a class that uses HttpClient and i have to fake the Stream response.

This is the code i'm trying to test.

            try
            {
                _httpClient.Timeout = TimeSpan.FromMinutes(10);
                _httpClient.BaseAddress = new Uri(BaseAddress);
                _httpClient.DefaultRequestHeaders.Accept.Clear();
                _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", _credentials);

                using (Stream s = _httpClient.GetStreamAsync(API_string).Result)  <---- this is the trouble line.
                using (StreamReader sr = new StreamReader(s))
                using (JsonReader reader = new JsonTextReader(sr))
                {
                    JsonSerializer serializer = new JsonSerializer();

                    return serializer.Deserialize<T>(reader); //breaks loop
                }
            }

From the test side, i can insert my custom HttpClientHandler and send back any response i want.

This is my Fake HttpClientHandler builder (I'm using Moq).

    public HttpClientHandler MockHttpClientHandler()
    {
        var requestUri = new Uri("Uri.Expected.To.Be.Called");
        var expectedResponse = "Response text"; <-- This is where i need to write the Object to be returned.

        var mockResponse = new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(expectedResponse) };
        var mockHandler = new Mock<HttpClientHandler>();
        mockHandler
            .Protected()
            .Setup<Task<HttpResponseMessage>>(
                "SendAsync",
                ItExpr.Is<HttpRequestMessage>(message => message.RequestUri == requestUri),
                // ItExpr.IsAny<HttpRequestMessage>(),
                ItExpr.IsAny<CancellationToken>())
            .Returns(Task.FromResult(mockResponse));

        return mockHandler.Object;
    }

My test breaks when it tries to run the return line, because whatever i'm sending back can't be deserialized. I just don't know what my Stream s should look like, and i can't see its contents by debugging either.

I'm fairly lost here. Maybe my approach is wrong?

Thanks for any help you can give me.

like image 383
Emiliano Rodriguez Avatar asked Sep 17 '25 23:09

Emiliano Rodriguez


1 Answers

        var stream = new MemoryStream();

        var httpResponse = new HttpResponseMessage
        {
            StatusCode = HttpStatusCode.OK,
            Content = new StreamContent(stream)
        };

        var handlerMock = new Mock<HttpMessageHandler>();
        handlerMock
            .Protected()
            .Setup<Task<HttpResponseMessage>>(
                  "SendAsync",
                  ItExpr.IsAny<HttpRequestMessage>(),
                  ItExpr.IsAny<CancellationToken>())
           .ReturnsAsync(httpResponse);
like image 50
Simon H Avatar answered Sep 20 '25 13:09

Simon H