我正在尝试为 HttpClient 服务编写一些单元测试,并且在尝试模拟 GetAccessToken() 函数中的部分代码时遇到了问题。
该服务接受一个 IHttpClientFactory。从我到目前为止所做的阅读看来,要正确地模拟它,我必须模拟 IHttpClientFactory,让它返回一个依赖于模拟 HttpMessageHandler 的新 HttpClient,我这样做是这样的:
var mockHttpClientFactory = new Mock<IHttpClientFactory>();
var mockHttpMessageHandler = new Mock<HttpMessageHandler>();
mockHttpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent("{'name':thecodebuzz,'city':'USA'}"),
});
var client = new HttpClient(mockHttpMessageHandler.Object);
mockHttpClientFactory.Setup(x => x.CreateClient(It.IsAny<string>())).Returns(client);
_httpClientService = new HttpClientService(mockHttpClientFactory.Object, mockConfig.Object);
这方面有效,我已经能够调用 CreateClient() 工作正常。但是,我尝试测试的函数调用了我的 GetAccessToken() 函数,该函数又调用了 client.GetDiscoveryAccessToken()。我猜 GetDiscoveryAccessToken() 函数需要被模拟,但我不确定如何继续。
我尝试使用模拟方法创建客户端模拟,并在调用 CreateClient 时返回它,如下所示:
var discoDoc = // Mocked disco doc code;
var client = new Mock<HttpClient>(mockHttpMessageHandler.Object);
client.Setup(x => x.GetDiscoveryDocumentAsync(It.IsAny<string>())).Returns(discoDoc);
mockHttpClientFactory.Setup(x => x.CreateClient(It.IsAny<string>())).Returns(client);
_httpClientService = new HttpClientService(mockHttpClientFactory.Object, mockConfig.Object);
不幸的是,我在告诉 CreateClient 函数返回什么的那一行出现了这个错误:“无法从 'Moq.Mock' 转换为 'System.Net.Http.HttpClient'”。我猜这是因为我需要返回一个真正的 HttpClient 而不是一个 Mocked 。
关于我可以从这里去哪里的任何想法?