如何在调用HttpClient GetStreamAsync时模拟Stream响应

时间:2018-05-16 19:56:54

标签: c# unit-testing testing moq

我正在尝试测试一个使用HttpClient的类,我必须伪造Stream响应。

这是我试图测试的代码。

            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
                }
            }

从测试方面,我可以插入我的自定义HttpClientHandler并发送回我想要的任何响应。

这是我的Fake HttpClientHandler构建器(我正在使用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;
    }

我的测试在尝试运行返回行时中断,因为无论我发回的是什么都无法反序列化。我只是不知道我的Stream应该是什么样的,我也无法通过调试看到它的内容。

我在这里很丢失。也许我的做法是错的?

感谢您提供任何帮助。

1 个答案:

答案 0 :(得分:0)

        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);