我正在使用Moq编写测试,并且能够模拟HttpClientHandler进行GetAsync()调用,但是当我尝试模拟PostAsync()时,它将返回null。有没有一种方法可以模拟该功能,而无需在整个HttpClient周围创建包装器?
下面是我模拟该功能的单元测试代码。
Mock<WebProxy> mockWebProxy = new Mock<WebProxy>();
mockWebProxy.Object.Address = new Uri(configuration.GetSection("TestProxy").Value);
mockWebProxy.Object.UseDefaultCredentials = true;
Mock<HttpClient> mockHttpClient = new Mock<HttpClient>();
var mockHttpClientHandler = new Mock<HttpClientHandler>();
mockHttpClientHandler.Object.Proxy = mockWebProxy.Object;
mockHttpClientHandler
.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.IsAny<HttpRequestMessage>(),
ItExpr.IsAny<CancellationToken>()
)
.ReturnsAsync(new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent("this is a test")
})
.Verifiable();
mockHttpClient = new Mock<HttpClient>(mockHttpClientHandler.Object, true);
然后这是我叫PostAsync():
var response = await httpClient.PostAsync(new Uri(url), stringContent);
PostAsync()在不模拟httpClient时起作用。但是,在进行模拟时,上面的响应为null。这告诉我正在使用模拟的HttpClient,因为没有响应,但是我不确定为什么它为null,而不是我模拟的不适用于GetAsync()的HttpResponseMessage。
答案 0 :(得分:1)
您将需要一个包装器。
您的设置是针对SendAsync
的,它在基类HttpMessageInvoker
中是虚拟的,因此可以覆盖,但是您要调用PostAsync
,它是公共的且不能覆盖。
关于HttpClient
的很酷的事情是,一旦将其包装,就可以重复使用。伸出一口子弹(如果可以的话)并将其包裹起来。 :-)