国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

ASP.NET Core針對一個使用HttpClient對象的類編寫單元測試詳解

2024-07-10 12:48:34
字體:
來源:轉載
供稿:網友

介紹

幾年前,微軟引入了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<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) {  return await Task.FromResult(_fakeResponse); }}

這里我添加了一個需要HttpResponseMessage構造函數,然后復寫了SendAsync方法, 在該方法中直接返回了構造函數中傳入的HttpResponseMessage對象。

編寫一個使用IHttpClientFactory接口的服務

下面我們需要編寫一個UserService類,這個類提供了一個GetUsers方法,來從遠程服務器端獲取用戶列表。

public class UserService{ private readonly IHttpClientFactory _httpFactory; public UserService(IHttpClientFactory httpFactory) {  _httpFactory = httpFactory; } public async Task<List<User>> GetUsers(string url) {  using (HttpClient httpclient = _httpFactory.CreateClient())  {   using (HttpResponseMessage response = await httpclient.GetAsync(url))   {    if (response.StatusCode == HttpStatusCode.OK)    {     List<User> users = await response.Content.ReadAsAsync<List<User>>();     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<User>    {     new User     {       FirstName = "John",       LastName = "Doe"     },     new User     {       FirstName = "John",       LastName = "Deere"     }    };    var httpClientFactoryMock = Substitute.For<IHttpClientFactory>();    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<List<User>>()   .And   .HaveCount(2)   .And   .Contain(x => x.FirstName == "John")   .And   .Contain(x => x.LastName == "Deere")   .And   .Contain(x => x.LastName == "Doe");  }}            
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 高密市| 德安县| 左权县| 厦门市| 新竹市| 潍坊市| 蕉岭县| 易门县| 长顺县| 贡嘎县| 盱眙县| 宣城市| 和硕县| 阿克苏市| 扎囊县| 镇雄县| 盐津县| 桑植县| 台湾省| 西畴县| 佛山市| 平原县| 朝阳市| 长宁区| 海门市| 集贤县| 北碚区| 双桥区| 长泰县| 那坡县| 镇康县| 昭平县| 涟源市| 襄樊市| 攀枝花市| 浠水县| 榆社县| 肇庆市| 炉霍县| 朝阳县| 浮山县|