• 热门专题

在ASP.NET Core里如何使用HttpClient为对象的类编写单元测试

作者:wy  发布日期:2019-01-09 08:39:00
  •   我相信大家对于在ASP.NET Core里如何以使用HttpClient为对象的类编写单元测试很感兴趣,在此篇文章中我们详细的将案例、步骤、过程都一步一步的记录在此,希望你看到这篇文章能够有所收获。

      几年前,微软引入了HttpClient类来替代HttpWebRequest来发送Web请求。这个新的类更易于使用,更加简洁,更具有异步性,且易于扩展。

      HttpClient类有一个可以接受HttpMessageHandler类对象的构造函数。HttpMessageHandler类对象可以接受一个请求(HttpRequestMessage), 并返回响应(HttpResponseMessage)。它的功能完全取决于它的实现。默认情况下HttpClient使用的是HttpClientHandler,HttpClientHandler是一个处理程序,它向网络服务器发送请求并从服务器返回响应。在本篇博文中,我们将通过继承DelegatingHandler来创建自己的HttpMessageHandler。

      为了实现以上功能,HttpClient对象不可以直接使用,而是需要与允许使用IHttpClientFactory接口进行模拟的依赖注入一起使用。

      让我们来伪造一个HttpMessageHandler

      下面的例子中,我们只讨论HttpResponseMessage, 不会处理HttpRequestMessage。

      以下是我伪造的一个HttpMessageHandler对象。

      public class FakeHttpMessageHandler : DelegatingHandler

      {

      private HttpResponseMessage _fakeResponse;

      public FakeHttpMessageHandler(HttpResponseMessage responseMessage)

      {

      _fakeResponse = responseMessage;

      }

      protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)

      {

      return await Task.FromResult(_fakeResponse);

      }

      }

      这里我添加了一个需要HttpResponseMessage构造函数,然后复写了SendAsync方法, 在该方法中直接返回了构造函数中传入的HttpResponseMessage对象。

      编写一个使用IHttpClientFactory接口的服务

    ASP.NET

      下面我们需要编写一个UserService类,这个类提供了一个GetUsers方法,来从远程服务器端获取用户列表。

      public class UserService

      {

      private readonly IHttpClientFactory _httpFactory;

      public UserService(IHttpClientFactory httpFactory)

      {

      _httpFactory = httpFactory;

      }

      public async Task> GetUsers(string url)

      {

      using (HttpClient httpclient = _httpFactory.CreateClient())

      {

      using (HttpResponseMessage response = await httpclient.GetAsync(url))

      {

      if (response.StatusCode == HttpStatusCode.OK)

      {

      List users = await response.Content.ReadAsAsync>();

      return users;

      }

      return null;

      }

      }

      }

      }

      以下是Api请求返回的用户类

      public class User

      {

      public string FirstName { get; set; }

      public string LastName { get; set; }

      }

      如你所见,使用HttpClientFactory允许我们模拟HttpClient实例化

      测试服务

      在下面的单元测试中,我们会使用XUnit、FluentAssertion、NSubstitute

      测试场景1: 模拟一个请求,返回2个用户

      public class UserServiceTests

      {

      [Fact]

      public async Task WhenACorrectUrlIsProvided_ServiceShouldReturnAlistOfUsers()

      {

      // Arrange

      var users = new List

      {

      new User

      {

      FirstName = "John",

      LastName = "Doe"

      },

      new User

      {

      FirstName = "John",

      LastName = "Deere"

      }

      };

      var httpClientFactoryMock = Substitute.For();

      var url = "http://good.uri";

      var fakeHttpMessageHandler = new FakeHttpMessageHandler(new HttpResponseMessage() {

      StatusCode = HttpStatusCode.OK,

      Content = new StringContent(JsonConvert.SerializeObject(users), Encoding.UTF8, "application/json")

      });

      var fakeHttpClient = new HttpClient(fakeHttpMessageHandler);

      httpClientFactoryMock.CreateClient().Returns(fakeHttpClient);

      // Act

      var service = new UserService(httpClientFactoryMock);

      var result = await service.GetUsers(url);

      // Assert

      result

      .Should()

      .BeOfType>()

      .And

      .HaveCount(2)

      .And

      .Contain(x => x.FirstName == "John")

      .And

      .Contain(x => x.LastName == "Deere")

      .And

      .Contain(x => x.LastName == "Doe");

      }

      }

      •在以上测试中,我们期望获取一个成功的响应,并得到2个用户的信息。

      •我们期望从Service中得到的数据是JSON格式的。

      •我们使用一个伪造的处理程序初始化了一个HttpClient对象,然后定义了我们期望的得到的伪造对象httpClientFactoryMock.CreateClient().Returns(fakeHttpClient);

      测试场景2: 模拟一个404错误,返回空数据

      public class UserServiceTests

      {

      [Fact]

      public async Task WhenABadUrlIsProvided_ServiceShouldReturnNull()

      {

      // Arrange

      var httpClientFactoryMock = Substitute.For();

      var url = "http://bad.uri";

      var fakeHttpMessageHandler = new FakeHttpMessageHandler(new HttpResponseMessage() {

      StatusCode = HttpStatusCode.NotFound

      });

      var fakeHttpClient = new HttpClient(fakeHttpMessageHandler);

      httpClientFactoryMock.CreateClient().Returns(fakeHttpClient);

      // Act

      var service = new UserService(httpClientFactoryMock);

      var result = await service.GetUsers(url);

      // Assert

      result

      .Should()

      .BeNullOrEmpty();

      }

      }

      和测试场景1类似,当一个Http请求返回Not Found, 它的结果集是Null

      不知道你看完之后有何感想呢?有没有收获到什么新的知识,自己的操作是否也完成了呢?希望大家以后也多多支持我们网站,这里有许多丰富的资讯,让你大饱眼福哦。

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规
易中彩票注册531| 936| 618| 24| 735| 66| 948| 966| 846| 552| 465| 834| 984| 690| 111| 123| 303| 723| 147| 948| 93| 129| 957| 267| 204| 960| 477| 30| 264| 948|