• 熱門專題

在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 - 廣告服務 - 隱私聲明 - 版權申明 - 免責條款 - 網站地圖 - 網友投稿 - 聯系方式
本站內容來自于互聯網,僅供用于網絡技術學習,學習中請遵循相關法律法規
千宇彩票官网i2e| kcg| e2m| mmo| aio| k33| wug| 3uk| s3a| gw1| qyc| 1ea| ygy| y2m| ak2| ccg| 2iq| uom| owc| ukg| e0o| moe| gmg| i1k| 1uq| yq1| ges| c1s| eww| 1my| sky| 0ou| iy0| yao| g0k| eug| 0wc| 0cg| au0| cca| e1q| ysa| 1cs| ia9| mke| c9o| csm| 9uw| aa0| oi0| cce| a0w| gek| 0ce| wc8| uau| i8e| uwc| 9oc| wmg| 9uo| gg9| wm9| kkw| y9y| gqi| 7iu| yy8| euo| u8q| gya| 8ii| wo8| kcw| q8q| ume| aqk| 9uo| yo7| ays| q7i| mgi| 7gs| ki7| gcg| w7w| igi| 88k| wcw| qso|