.NET Core 2.1 附带了这个名为 HttpClientFactory
的新工厂,但我无法弄清楚如何模拟它以对包含 REST 服务调用的某些方法进行单元测试。
正在使用 .NET Core IoC 容器注入(inject)工厂,该方法所做的是从工厂创建一个新的客户端:
var client = _httpClientFactory.CreateClient();
然后使用客户端从 REST 服务获取数据:
var result = await client.GetStringAsync(url);
最佳答案
HttpClientFactory
派生自 IHttpClientFactory
Interface所以这只是创建一个模拟界面的问题
var mockFactory = new Mock<IHttpClientFactory>();
根据您需要客户端的用途,您需要设置模拟以返回用于测试的 HttpClient
。
然而,这需要一个实际的 HttpClient
。
var clientHandlerStub = new DelegatingHandlerStub();
var client = new HttpClient(clientHandlerStub);
mockFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(client);
IHttpClientFactory factory = mockFactory.Object;
然后可以在进行测试时将工厂注入(inject)到被测依赖系统中。
如果您不希望客户端调用实际的端点,那么您将需要创建一个假的委托(delegate)处理程序来拦截请求。
用于伪造请求的处理程序 stub 示例
public class DelegatingHandlerStub : DelegatingHandler {
private readonly Func<HttpRequestMessage, CancellationToken, Task<HttpResponseMessage>> _handlerFunc;
public DelegatingHandlerStub() {
_handlerFunc = (request, cancellationToken) => Task.FromResult(request.CreateResponse(HttpStatusCode.OK));
}
public DelegatingHandlerStub(Func<HttpRequestMessage, CancellationToken, Task<HttpResponseMessage>> handlerFunc) {
_handlerFunc = handlerFunc;
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) {
return _handlerFunc(request, cancellationToken);
}
}
摘 self 在这里给出的答案
假设你有一个 Controller
[Route("api/[controller]")]
public class ValuesController : Controller {
private readonly IHttpClientFactory _httpClientFactory;
public ValuesController(IHttpClientFactory httpClientFactory) {
_httpClientFactory = httpClientFactory;
}
[HttpGet]
public async Task<IActionResult> Get() {
var client = _httpClientFactory.CreateClient();
var url = "http://example.com";
var result = await client.GetStringAsync(url);
return Ok(result);
}
}
并想测试 Get()
操作。
public async Task Should_Return_Ok() {
//Arrange
var expected = "Hello World";
var mockFactory = new Mock<IHttpClientFactory>();
var configuration = new HttpConfiguration();
var clientHandlerStub = new DelegatingHandlerStub((request, cancellationToken) => {
request.SetConfiguration(configuration);
var response = request.CreateResponse(HttpStatusCode.OK, expected);
return Task.FromResult(response);
});
var client = new HttpClient(clientHandlerStub);
mockFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(client);
IHttpClientFactory factory = mockFactory.Object;
var controller = new ValuesController(factory);
//Act
var result = await controller.Get();
//Assert
result.Should().NotBeNull();
var okResult = result as OkObjectResult;
var actual = (string) okResult.Value;
actual.Should().Be(expected);
}
关于c# - 如何使用 Moq 在 .NET Core 2.1 中模拟新的 HttpClientFactory,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54227487/