首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >net核心单元测试中的http类型化客户端

net核心单元测试中的http类型化客户端
EN

Stack Overflow用户
提问于 2019-06-10 13:18:11
回答 2查看 562关注 0票数 0

如何对调用http类型化客户端的服务进行单元测试?在https://learn.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-2.2#typed-clients中给出的示例不使用接口。

代码语言:javascript
运行
复制
public GitHubService(HttpClient client)

在使用xunit/moq进行单元测试时,是否需要为类型化客户端创建接口?或者我不需要对这个服务进行单元测试。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-06-10 13:38:52

如果您的服务类设计正确,那么单元测试就没有什么意义了。您的方法应该只是封装对HttpClient的调用,抽象URL/headers/connection/等等。从一般意义上说,您可以合理地确定HttpClient工作,因此本质上没有真正的代码需要测试。再说一次,那是假设你做得对。

如果您确实需要更复杂的逻辑,那么您应该有一个将这个简单的服务类作为依赖项的类,而复杂的逻辑应该放在那里。您的服务类可以实现一个接口,所以最好在这一点上进行。

当然,您可以在您的服务类上进行集成测试,这将确保它按应有的方式工作,实际上调用API或其传真。

票数 1
EN

Stack Overflow用户

发布于 2019-06-10 13:36:38

我不明白你的意思

http类型化客户机

但是,如果像在这个示例中一样,您希望测试一个使用HttpClient的类,要么为HttpClient创建一个包装器,然后使用依赖项注入传递它的接口(这样就可以模拟它),要么利用HttpClient的HttpClient构造函数参数。

使HttpClient成为构造函数参数,并在测试中创建代码,如下所示:

代码语言:javascript
运行
复制
var mockHttpMessageHandler = new Mock<HttpMessageHandler>();
mockHttpMessageHandler.Protected()
   .Setup<Task<HttpResponseMessage>>(
      "SendAsync",
      ItExpr.IsAny<HttpRequestMessage>(), // Customise this as you want
      ItExpr.IsAny<CancellationToken>()
   )
   // Create the response you want to return
   .ReturnsAsync(new HttpResponseMessage()
   {    
      StatusCode = HttpStatusCode.OK,
      Content = new StringContent("[{'prop1': 100,'prop2': 'value'}]"),
   });

// Create an HttpClient using the mocked message handler
var httpClient = new HttpClient(mockHttpMessageHandler.Object)
{
   BaseAddress = new Uri("http://anyurl.com/"),
};

var testedService = new MyServiceUnderTest(httpClient);

var result = await testedService.MethodUnderTest(parameters [...]);

为了简化moq的设置,限制预期的HttpRequestMessage,我使用了这个助手方法。

代码语言:javascript
运行
复制
    /// <summary>
    /// Setup the mocked http handler with the specified criteria
    /// </summary>
    /// <param name="httpStatusCode">Desired status code returned in the response</param>
    /// <param name="jsonResponse">Desired Json response</param>
    /// <param name="httpMethod">Post, Get, Put ...</param>
    /// <param name="uriSelector">Function used to filter the uri for which the setup must be applied</param>
    /// <param name="bodySelector">Function used to filter the body of the requests for which the setup must be applied</param>
    private void SetupHttpMock(HttpStatusCode httpStatusCode, string jsonResponse, HttpMethod httpMethod, Func<string, bool> uriSelector, Func<string, bool> bodySelector = null)
    {
        if (uriSelector == null) uriSelector = (s) => true;
        if (bodySelector == null) bodySelector = (s) => true;

        _messageHandlerMock
            .Protected()
            .Setup<Task<HttpResponseMessage>>("SendAsync",
                ItExpr.Is<HttpRequestMessage>(m =>
                    m.Method == httpMethod &&
                    bodySelector(m.Content.ReadAsStringAsync().Result) &&
                    uriSelector(m.RequestUri.ToString())),
                ItExpr.IsAny<CancellationToken>())
            .ReturnsAsync(new HttpResponseMessage
            {
                StatusCode = httpStatusCode,
                Content = jsonResponse == null ? null : new StringContent(jsonResponse, Encoding.UTF8, "application/json")
            });
    }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56527226

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档