如何使用 ASP. NET核心中的 HttpClient为一个对象类编写单元测试
时间:2020-12-02

相信大家对如何在ASP.NETCore中编写单元测试很感兴趣,在本文中,我们将一步一步详细记录案例、步骤和过程。希望你能从这篇文章中看到一些收获。

几年前,微软推出了HttpClient类代替HttpWebRequest来发送Web请求。这个新类更容易使用,更简洁,更异步,易于扩展。

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

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

让我们伪造一个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,不处理HttpRequestMessage。

下面是一个伪造的HttpMessageHandler对象。

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

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

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;


  }


  }


  }


  }

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

public class User


  {


  public string FirstName { get; set; }


  public string LastName { get; set; }


  }

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

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 = ";;


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


  }


  }

测试服务。

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

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

在上面的测试中,我们期望得到一个成功的响应,得到两个用户的信息。

我们希望从该服务获得的数据是JSON格式的。

我们使用一个伪处理程序来初始化一个HttpClient对象,然后定义这个伪对象httpClientFactoryMock。createClient()。返回(fakehttpclient)。

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

public class UserServiceTests


  {


  [Fact]


  public async Task WhenABadUrlIsProvided_ServiceShouldReturnNull()


  {


  // Arrange


  var httpClientFactoryMock = Substitute.For();


  var url = ";;


  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请求返回NotFound时,其结果集为空。

不知道你看完之后是什么感受?有没有获得什么新知识,完成自己的操作?希望以后大家支持我们的网站。这里有很多信息,会让你大饱眼福。


本文来源网络,如有侵权,请联系752824794@qq.com或致电150 1372 4571 。