如何使用Moq在.NET Core 2.1中模拟新的HttpClientFactory [英] How to mock the new HttpClientFactory in .NET Core 2.1 using Moq

查看:197
本文介绍了如何使用Moq在.NET Core 2.1中模拟新的HttpClientFactory的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

.NET Core 2.1带有一个名为HttpClientFactory的新工厂,但是我不知道如何模拟它来对包括REST服务调用的某些方法进行单元测试.

.NET Core 2.1 comes with this new factory called HttpClientFactory, but I can't figure out how to mock it to unit test some methods that include REST service calls.

正在使用.NET Core IoC容器注入工厂,该方法的作用是从工厂创建新客户端:

The factory is being injected using .NET Core IoC container, and what the method does is create a new client from the factory:

var client = _httpClientFactory.CreateClient();

然后使用客户端从REST服务获取数据:

And then using the client to get data from a REST service:

var result = await client.GetStringAsync(url);

推荐答案

HttpClientFactory源自

The HttpClientFactory is derived from IHttpClientFactory Interface So it is just a matter of creating a mock of the interface

var mockFactory = new Mock<IHttpClientFactory>();

根据客户端需要的内容,然后需要设置模拟以返回测试的HttpClient.

Depending on what you need the client for, you would then need to setup the mock to return a HttpClient for the test.

但是,这需要实际的HttpClient.

This however requires an actual HttpClient.

var clientHandlerStub = new DelegatingHandlerStub();
var client = new HttpClient(clientHandlerStub);

mockFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(client);

IHttpClientFactory factory = mockFactory.Object;

然后可以在进行测试时将工厂注入到受测试的依赖系统中.

The factory can then be injected into the dependent system under test when exercising the test.

如果您不希望客户端调用实际的端点,则需要创建一个伪造的委托处理程序来拦截请求.

If you do not want the client calling actual endpoints then you will need to create a fake delegate handler to intercept the requests.

用于伪造请求的处理程序存根示例

Example of the handler stub used to fake the requests

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);
    }
}

根据我在这里给出的答案

Taken from an answer I gave here

参考使用Moq模拟HttpClient

假设您有一个控制器

[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);
}

这篇关于如何使用Moq在.NET Core 2.1中模拟新的HttpClientFactory的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆