[英]How to Mock GetDiscoveryDocumentAsync When Unit Testing HttpClient?
我正在嘗試為 HttpClient 服務編寫一些單元測試,並且在嘗試模擬 GetAccessToken() function 中的部分代碼時遇到了問題。
該服務接受一個 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() 工作正常。 然而,function 我正在嘗試測試調用我的 GetAccessToken() function,然后調用 client.GetDiscoveryAccessToken()。 我猜 GetDiscoveryAccessToken() function 需要被嘲笑,但我不確定如何繼續。
我嘗試使用模擬方法創建客戶端模擬,並在調用 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 function 要返回什么的行上收到此錯誤:“無法從 'Moq.Mock' 轉換為 'System.Net.Http.HttpClient'”。 我猜這是因為我需要返回一個真正的 HttpClient 而不是一個 Mocked 。
關於我可以從這里 go 到哪里的任何想法?
您快到了,對於 CreateClient,您將返回 Moq 的 Object,而不是 Mocked object。 只需要返回模擬的 object 如下。
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.Object);
_httpClientService = new HttpClientService(mockHttpClientFactory.Object, mockConfig.Object);
讓我知道這是否是您所期望的。
實際上沒有辦法嘲笑這一點。 對此進行測試的唯一方法是以與 IdentityModel 團隊類似的方式進行 - 使用他們自己的 HttpMessageHandler 實現。 ( NetworkHandler )然后您可以執行以下操作:
HttpResponseMessage GetDiscoveryResponse()
{
var wellKnown = File.ReadAllText("openid-configuration.json");
var response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(wellKnown)
};
return response;
};
var httpClient = new HttpClient(new NetworkHandler(request => {
if (request.RequestUri.AbsoluteUri.Contains("openid-configuration"))
{
return GetDiscoveryResponse();
}
throw new NotImplementedException();
}));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.