Tung.HttpClientTestExtensions
0.1.0
dotnet add package Tung.HttpClientTestExtensions --version 0.1.0
NuGet\Install-Package Tung.HttpClientTestExtensions -Version 0.1.0
<PackageReference Include="Tung.HttpClientTestExtensions" Version="0.1.0" />
paket add Tung.HttpClientTestExtensions --version 0.1.0
#r "nuget: Tung.HttpClientTestExtensions, 0.1.0"
// Install Tung.HttpClientTestExtensions as a Cake Addin #addin nuget:?package=Tung.HttpClientTestExtensions&version=0.1.0 // Install Tung.HttpClientTestExtensions as a Cake Tool #tool nuget:?package=Tung.HttpClientTestExtensions&version=0.1.0
Tiện ích mở rộng thử nghiệm HttpClient
Tiện ích mở rộng để kiểm tra điểm cuối HTTP và giải tuần tự hóa kết quả. Hiện đang làm việc với XUnit.
Cài đặt
Thêm gói NuGet:
dotnet add package Tung.HttpClientTestExtensions
Trong thử nghiệm của bạn, hãy thêm không gian tên:
using Tung.HttpClientTestExtensions;
Cách sử dụng
Nếu bạn có mã kiểm tra hiện tại trông giống như thế này:
public class DoctorsList : IClassFixture<CustomWebApplicationFactory<Startup>>
{
private readonly HttpClient _client;
private readonly ITestOutputHelper _outputHelper;
public DoctorsList(CustomWebApplicationFactory<Startup> factory,
ITestOutputHelper outputHelper)
{
_client = factory.CreateClient();
_outputHelper = outputHelper;
}
[Fact]
public async Task Returns3Doctors()
{
var response = await _client.GetAsync("/api/doctors");
response.EnsureSuccessStatusCode();
var stringResponse = await response.Content.ReadAsStringAsync();
_outputHelper.WriteLine(stringResponse);
var result = JsonSerializer.Deserialize<ListDoctorResponse>(stringResponse,
Constants.DefaultJsonOptions);
Assert.Equal(3, result.Doctors.Count());
Assert.Contains(result.Doctors, x => x.Name == "Dr. Tung");
}
}
Bây giờ bạn có thể cập nhật thử nghiệm để loại bỏ tất cả ngoại trừ một dòng trước các xác nhận:
[Fact]
public async Task Returns3Doctors()
{
var result = await _client.GetAndDeserialize<ListDoctorResponse>("/api/doctors", _outputHelper);
Assert.Equal(3, result.Doctors.Count());
Assert.Contains(result.Doctors, x => x.Name == "Dr. Tung");
}
Nếu cần xác minh điểm cuối trả về 404, bạn có thể sử dụng phương pháp này:
[Fact]
public async Task ReturnsNotFoundGivenInvalidAuthorId()
{
int invalidId = 9999;
var response = await _client.GetAsync(Routes.Authors.Get(invalidId));
response.EnsureNotFound();
}
Danh sách các phương thức trợ giúp đi kèm
HttpClient
Tất cả các phương pháp này đều là phần mở rộng trên HttpClient
; các mẫu sau đây giả sử client
là tệp HttpClient
. Tất cả các phương thức đều có một tùy chọn ITestOutputHelper
, là loại xUnit.
GET
// GET and return an object T
AuthorDto result = await client.GetAndDeserializeAsync("/authors/1", _testOutputHelper);
// GET and return response as a string
string result = client.GetAndReturnStringAsync("/healthcheck");
// GET and ensure response contains a substring
string result = client.GetAndEnsureSubstringAsync("/healthcheck", "OMG!");
// GET and assert a 302 is returned
var client = _factory.CreateClient(new WebApplicationFactoryClientOptions() { AllowAutoRedirect = false });
await client.GetAndEnsureRedirectAsync("/oldone, "/newone");
// GET and assert a 400 is returned
await client.GetAndEnsureBadRequestAsync("/authors?page");
// GET and assert a 401 is returned
await client.GetAndEnsureUnauthorizedAsync("/authors/1");
// GET and assert a 403 is returned
await client.GetAndEnsureForbiddenAsync("/authors/1");
// GET and assert a 404 is returned
await client.GetAndEnsureNotFoundAsync("/authors/-1");
// GET and assert a 405 is returned
await client.GetAndEnsureMethodNotAllowedAsync("/wrongendpoint", content)
POST
// NOTE: There's a helper for this now, too (see below)
var content = new StringContent(JsonSerializer.Serialize(dto), Encoding.UTF8, "application/json");
// POST and return an object T
AuthorDto result = await client.PostAndDeserializeAsync("/authors", content);
// POST and ensure response contains a substring
string result = client.PostAndEnsureSubstringAsync("/authors", content, "OMG!");
// POST and assert a 302 is returned
var client = _factory.CreateClient(new WebApplicationFactoryClientOptions() { AllowAutoRedirect = false });
await client.PostAndEnsureRedirectAsync("/oldone", content, "/newone");
// POST and assert a 400 is returned
await client.PostAndEnsureBadRequestAsync("/authors", "banana");
// POST and assert a 401 is returned
await client.PostAndEnsureUnauthorizedAsync("/authors", content);
// POST and assert a 403 is returned
await client.PostAndEnsureForbiddenAsync("/authors", content);
// POST and assert a 404 is returned
await client.PostAndEnsureNotFoundAsync("/wrongendpoint", content)
// POST and assert a 405 is returned
await client.PostAndEnsureMethodNotAllowedAsync("/wrongendpoint", content)
PUT
var content = new StringContent(JsonSerializer.Serialize(dto), Encoding.UTF8, "application/json");
// PUT and return an object T
AuthorDto result = await client.PutAndDeserializeAsync("/authors/1", content);
// PUT and ensure response contains a substring
string result = client.PutAndEnsureSubstringAsync("/authors/1", content, "OMG!");
// PUT and assert a 302 is returned
var client = _factory.CreateClient(new WebApplicationFactoryClientOptions() { AllowAutoRedirect = false });
await client.PutAndEnsureRedirectAsync("/oldone", content, "/newone");
// PUT and assert a 400 is returned
await client.PutAndEnsureBadRequestAsync("/authors/1", "banana");
// PUT and assert a 401 is returned
await client.PutAndEnsureUnauthorizedAsync("/authors/1", content);
// PUT and assert a 403 is returned
await client.PutAndEnsureForbiddenAsync("/authors/1", content);
// PUT and assert a 404 is returned
await client.PutAndEnsureNotFoundAsync("/wrongendpoint", content)
// PUT and assert a 405 is returned
await client.PutAndEnsureMethodNotAllowedAsync("/wrongendpoint", content)
DELETE
// DELETE and return an object T
AuthorDto result = await client.DeleteAndDeserializeAsync("/authors/1");
// DELETE and ensure response contains a substring
string result = client.DeleteAndEnsureSubstringAsync("/authors/1", "OMG!");
// DELETE and assert a 204 is returned
await client.DeleteAndEnsureNoContentAsync("/authors/1");
// DELETE and assert a 302 is returned
var client = _factory.CreateClient(new WebApplicationFactoryClientOptions() { AllowAutoRedirect = false });
await client.DeleteAndEnsureRedirectAsync("/oldone", "/newone");
// DELETE and assert a 400 is returned
await client.DeleteAndEnsureBadRequestAsync("/authors/1");
// DELETE and assert a 401 is returned
await client.DeleteAndEnsureUnauthorizedAsync("/authors/1");
// DELETE and assert a 403 is returned
await client.DeleteAndEnsureForbiddenAsync("/authors/1");
// DELETE and assert a 404 is returned
await client.DeleteAndEnsureNotFoundAsync("/wrongendpoint");
// DELETE and assert a 405 is returned
await client.DeleteAndEnsureMethodNotAllowedAsync("/wrongendpoint", content)
HttpResponseMessage
Tất cả các phương pháp này đều là phần mở rộng trên HttpResponseMessage
.
// Assert a response has a status code of 204
response.EnsureNoContent();
// Assert a response has a status code of 302
response.EnsureRedirect("/newone");
// Assert a response has a status code of 400
response.EnsureBadRequest();
// Assert a response has a status code of 401
response.EnsureUnauthorized();
// Assert a response has a status code of 403
response.EnsureForbidden();
// Assert a response has a status code of 404
response.EnsureNotFound();
// Assert a response has a status code of 405
response.EnsureMethodNotAllowed();
// Assert a response has a given status code
response.Ensure(HttpStatusCode.Created);
// Assert a response contains a substing
response.EnsureContainsAsync("OMG!", _testOutputHelper);
StringContentHelpers
Các tiện ích mở rộng HttpContent
mà bạn thường muốn trả về một StringContent
loại khi bạn tuần tự hóa DTO của mình thành JSON.
// Convert a C# DTO to a StringContent JSON type
var authorDto = new ("Tung");
var content = StringContentHelpers.FromModelAsJson(authorDto);
// now you can use this with a POST, PUT, etc.
AuthorDto result = await client.PostAndDeserializeAsync("/authors", content);
// Or you can do it all in one line (assuming you already have the DTO)
AuthorDto result = await client.PostAndDeserializeAsync("/authors",
StringContentHelpers.FromModelAsJson(authorDto));
Notes
- Hiện tại, dự án này được kết hợp với xUnit nhưng nếu quan tâm thì có thể chia nhỏ phụ thuộc ITestOutputHelper với xóa/ tùy chọn/ hoán đổi
- Trợ giúp bổ sung cho các hành động khác đang được lên kế hoạch
- Dự án sử dụng System.Text.Json với các tùy chọn CamelCase mặc định mà tôi thấy hữu ích nhất trong các dự án của mình. Nó cũng có thể được mở rộng bằng các cách tốt hơn.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net6.0
- Microsoft.AspNetCore.Mvc.Testing (>= 6.0.8)
- System.Text.Json (>= 6.0.5)
- xunit.abstractions (>= 2.0.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
0.1.0 | 114 | 1/15/2024 |
Initial version.