调用HttpClient GetStreamAsync时如何模拟Stream响应
解决HttpClient GetStreamAsync伪造响应的反序列化问题
看起来你遇到的核心问题是伪造的响应内容格式不合法,导致后续的JSON反序列化失败。咱们一步步来修复:
问题根源
你的测试代码里有两个关键疏漏:
- 直接用普通字符串
"Response text"作为响应内容,这不是合法的JSON格式,反序列化器无法将它转换成目标泛型类型T - 创建
StringContent时没有指定正确的媒体类型(application/json),虽然HttpClient可能会忽略这个,但明确设置能避免反序列化器因为内容类型不匹配而出错
修复后的伪造Handler代码
首先,你需要把预期返回的测试对象序列化为JSON字符串,然后给StringContent指定正确的媒体类型和编码。下面是修改后的完整代码:
using Newtonsoft.Json; // 如果项目用System.Text.Json,替换为对应命名空间 using System.Net.Http; using System.Text; using Moq; using Moq.Protected; public HttpClientHandler MockHttpClientHandler<T>(T expectedResponseObject, string expectedFullRequestUri) { // 1. 将预期对象序列化为合法的JSON字符串 var expectedResponseJson = JsonConvert.SerializeObject(expectedResponseObject); // 2. 创建带有正确媒体类型的响应内容 var mockResponse = new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent( expectedResponseJson, Encoding.UTF8, "application/json" // 明确指定JSON媒体类型 ) }; var mockHandler = new Mock<HttpClientHandler>(); mockHandler .Protected() .Setup<Task<HttpResponseMessage>>( "SendAsync", // 匹配完整的请求URI(注意BaseAddress + API_string的拼接结果) ItExpr.Is<HttpRequestMessage>(message => message.RequestUri.AbsoluteUri == expectedFullRequestUri), ItExpr.IsAny<CancellationToken>()) .Returns(Task.FromResult(mockResponse)); return mockHandler.Object; }
使用说明
- 拼接正确的请求URI:在测试方法里,把待测试类的
BaseAddress和API_string拼接成完整的URI,比如:var expectedFullUri = new Uri(new Uri(BaseAddress), API_string).AbsoluteUri; - 创建测试对象:实例化你期望返回的
T类型对象,填充测试数据:var testResponse = new YourTargetType { // 填充属性值,比如 Id = 1, Name = "Test Demo" }; - 注入伪造Handler:用这个伪造的Handler创建HttpClient,再注入到待测试的类中:
var fakeHandler = MockHttpClientHandler(testResponse, expectedFullUri); var testHttpClient = new HttpClient(fakeHandler); // 把testHttpClient注入到你的待测试类中(比如通过构造函数)
额外注意事项
- 如果你在项目中使用的是
System.Text.Json而不是Newtonsoft.Json,把序列化代码改成:var expectedResponseJson = System.Text.Json.JsonSerializer.Serialize(expectedResponseObject); - 待测试代码里用
.Result调用异步方法GetStreamAsync可能会导致死锁,建议改成异步等待(await),不过这是测试之外的优化点。
内容的提问来源于stack exchange,提问作者Emiliano Rodriguez
相关产品推荐
相关产品推荐

