Tar*_*rta 5 c# unit-testing moq xunit asp.net-core
我正在为这个简单地调用外部 API 的小服务编写一个简单的单元测试:
public class ApiCaller : IApiCaller
{
private readonly IHttpClientFactory _httpFactory;
public ApiCaller(IHttpClientFactory httpFactory)
{
_httpFactory = httpFactory;
}
public async Task<T> GetResponseAsync<T>(Uri url)
{
using (HttpClient client = _httpFactory.CreateClient())
{
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.Timeout = TimeSpan.FromSeconds(20);
using (HttpResponseMessage response = await client.GetAsync(url))
{
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<T>(responseBody);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的第一个问题是:模拟并因此测试此类服务似乎不是很常见的做法,我想知道是否有一些具体的解释。
其次,我尝试编写一个简单的单元测试,但我无法模拟GetAsync调用,因为 HttpClient 没有实现任何接口。
public class ApiCallerTest
{
private readonly ApiCaller _target;
private readonly Mock<IHttpClientFactory> _httpClientFactory;
public ApiCallerTest()
{
_httpClientFactory = new Mock<IHttpClientFactory>();
_target = new ApiCaller(_httpClientFactory.Object);
}
[Fact]
public void WhenACorrectUrlIsProvided_ServiceShouldReturn()
{
var client = new HttpClient();
_httpClientFactory.Setup(x => x.CreateClient(It.IsAny<string>())).Returns(client);
var httpMessageHandler = new Mock<HttpMessageHandler>();
}
}
Run Code Online (Sandbox Code Playgroud)
小智 8
无论您在 HttpClient 类中使用哪种方法(GetAsync、PostAsync 等),您都应该使用下面的代码。所有这些方法都是为了程序员的方便而创建的。他们所做的是使用HttpMessageHandler 类的SendAsync方法。
var mockHttpMessageHandler = new Mock<HttpMessageHandler>();
// Setup Protected method on HttpMessageHandler mock.
mockHttpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.IsAny<HttpRequestMessage>(),
ItExpr.IsAny<CancellationToken>()
)
.ReturnsAsync((HttpRequestMessage request, CancellationToken token) =>
{
HttpResponseMessage response = new HttpResponseMessage();
// configure your response here
return response;
});
Run Code Online (Sandbox Code Playgroud)
然后你这样使用它:
var httpClient = new HttpClient(mockHttpMessageHandler.Object);
var result = await httpClient.GetAsync(url, cancellationToken);
Run Code Online (Sandbox Code Playgroud)
您还可以在这里查看如何为 httpclient getasync 方法创建模拟?
首先设置你的 MockHttpMessageHandler
并将其传递给你的HttpClient
. 然后你可以为GetAsync
处理程序上的方法设置一个 Mock,如下所示:
var httpMessageHandler = new Mock<HttpMessageHandler>();
// Setup Protected method on HttpMessageHandler mock.
httpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>(
"GetAsync",
ItExpr.IsAny<string>(),
ItExpr.IsAny<CancellationToken>()
)
.ReturnsAsync((HttpRequestMessage request, CancellationToken token) =>
{
HttpResponseMessage response = new HttpResponseMessage();
// Setup your response for testing here.
return response;
});
var client = new HttpClient(httpMessageHandler.Object);
Run Code Online (Sandbox Code Playgroud)
这是从我用来模拟的单元测试修改而来的SendAsync
,但它应该非常相似。
归档时间: |
|
查看次数: |
3256 次 |
最近记录: |