ASP.NET Core: Kiểm thử dịch vụ gRPC trong ASP.NET Core
Trong bài viết này
- Ví dụ về dịch vụ có thể kiểm thử
- Dịch vụ gRPC thử nghiệm đơn vị
- Kiểm thử tích hợp dịch vụ gRPC
- Tài nguyên bổ sung
Kiểm thử (Testing) là một khía cạnh quan trọng của việc xây dựng phần mềm ổn định và có thể bảo trì. Bài viết này thảo luận về cách kiểm thử các dịch vụ gRPC của ASP.NET Core.
Có ba cách tiếp cận phổ biến để thử nghiệm các dịch vụ gRPC:
- Kiểm thử đơn vị: Kiểm thử các dịch vụ gRPC trực tiếp từ thư viện kiểm thử đơn vị.
- Kiểm thử tích hợp: Ứng dụng gRPC được lưu trữ trong TestServer, một máy chủ kiểm thử trong bộ nhớ của gói Microsoft.AspNetCore.TestHost. Các dịch vụ gRPC được kiểm thử bằng cách gọi chúng bằng ứng dụng khách gRPC từ thư viện thử nghiệm đơn vị.
- Kiểm thử thủ công: Kiểm thử máy chủ gRPC bằng các lời gọi đặc biệt. Để biết thông tin về cách sử dụng công cụ dòng lệnh và giao diện người dùng với các dịch vụ gRPC, hãy xem Kiểm thử dịch vụ gRPC bằng Postman hoặc gRPCurl trong ASP.NET Core.
Trong thử nghiệm đơn vị, chỉ có dịch vụ gRPC được tham gia. Các phần phụ thuộc được đưa vào dịch vụ phải được mô phỏng. Trong thử nghiệm tích hợp, dịch vụ gRPC và cơ sở hạ tầng phụ trợ của nó là một phần của thử nghiệm. Điều này bao gồm khởi động ứng dụng, chèn phần phụ thuộc, định tuyến và xác thực cũng như ủy quyền.
Ví dụ về dịch vụ có thể kiểm thử
Để chứng minh các thử nghiệm dịch vụ, hãy xem lại dịch vụ sau trong ứng dụng mẫu.
Xem hoặc tải xuống code mẫu ( cách tải xuống )
TesterService
sẽ trả về lời chào bằng bốn loại phương thức của gRPC.
public class TesterService : Tester.TesterBase
{
private readonly IGreeter _greeter;
public TesterService(IGreeter greeter)
{
_greeter = greeter;
}
public override Task<HelloReply> SayHelloUnary(HelloRequest request,
ServerCallContext context)
{
var message = _greeter.Greet(request.Name);
return Task.FromResult(new HelloReply { Message = message });
}
public override async Task SayHelloServerStreaming(HelloRequest request,
IServerStreamWriter<HelloReply> responseStream, ServerCallContext context)
{
var i = 0;
while (!context.CancellationToken.IsCancellationRequested)
{
var message = _greeter.Greet($"{request.Name} {++i}");
await responseStream.WriteAsync(new HelloReply { Message = message });
await Task.Delay(1000);
}
}
public override async Task<HelloReply> SayHelloClientStreaming(
IAsyncStreamReader<HelloRequest> requestStream, ServerCallContext context)
{
var names = new List<string>();
await foreach (var request in requestStream.ReadAllAsync())
{
names.Add(request.Name);
}
var message = _greeter.Greet(string.Join(", ", names));
return new HelloReply { Message = message };
}
public override async Task SayHelloBidirectionalStreaming(
IAsyncStreamReader<HelloRequest> requestStream,
IServerStreamWriter<HelloReply> responseStream,
ServerCallContext context)
{
await foreach (var request in requestStream.ReadAllAsync())
{
await responseStream.WriteAsync(
new HelloReply { Message = _greeter.Greet(request.Name) });
}
}
}
Dịch vụ gRPC ở trên:
- Tuân theo Nguyên tắc phụ thuộc rõ ràng.
- Yêu cầu tính năng chèn phụ thuộc (DI) sẽ cung cấp một phiên bản của
IGreeter
. - Có thể được kiểm thử bằng dịch vụ
IGreeter
được mô phỏng bằng cách sử dụng framework đối tượng mô phỏng, chẳng hạn như Moq. Một đối tượng giả là một đối tượng được tạo với một tập hợp các property và hành vi phương thức được xác định trước được sử dụng để thử nghiệm. Để biết thêm thông tin, hãy xem Kiểm thử tích hợp trong ASP.NET Core.
Dịch vụ gRPC thử nghiệm đơn vị
Thư viện kiểm thử đơn vị có thể kiểm thử trực tiếp các dịch vụ gRPC bằng cách gọi các phương thức của nó. Các unit test sẽ kiểm thử dịch vụ gRPC một cách riêng biệt.
[Fact]
public async Task SayHelloUnaryTest()
{
// Arrange
var mockGreeter = new Mock<IGreeter>();
mockGreeter.Setup(
m => m.Greet(It.IsAny<string>())).Returns((string s) => $"Hello {s}");
var service = new TesterService(mockGreeter.Object);
// Act
var response = await service.SayHelloUnary(
new HelloRequest { Name = "Joe" }, TestServerCallContext.Create());
// Assert
mockGreeter.Verify(v => v.Greet("Joe"));
Assert.Equal("Hello Joe", response.Message);
}
Unit test ở trên:
- Mô phỏng
IGreeter
sử dụng Moq. - Thực thi phương thức
SayHelloUnary
với message yêu cầu và fileServerCallContext
. Tất cả các phương thức dịch vụ đều có một đối sốServerCallContext
. Trong thử nghiệm này, kiểu được cung cấp bằng phương thức trợ giúpTestServerCallContext.Create()
. Phương thức trợ giúp này được bao gồm trong code mẫu. - Đưa ra những khẳng định:
- Xác minh tên yêu cầu được chuyển tới
IGreeter
. - Dịch vụ trả về message trả lời dự kiến.
- Xác minh tên yêu cầu được chuyển tới
Kiểm thử đơn vị HttpContext
trong các phương thức gRPC
Các phương thức gRPC có thể truy cập HttpContext của yêu cầu bằng phương thức mở rộng ServerCallContext.GetHttpContext
. Để kiểm thử đơn vị một phương thức sử dụng HttpContext
, ngữ cảnh phải được định cấu hình trong quá trình thiết lập kiểm thử. Nếu HttpContext không được định cấu hình thì GetHttpContext
trả về null
.
Để định cấu hình HttpContext
trong quá trình thiết lập thử nghiệm, hãy tạo một phiên bản mới và thêm nó vào collection ServerCallContext.UserState
bằng khóa __HttpContext
.
var httpContext = new DefaultHttpContext();
var serverCallContext = TestServerCallContext.Create();
serverCallContext.UserState["__HttpContext"] = httpContext;
Thực thi các phương thức dịch vụ với ngữ cảnh lời gọi này để sử dụng thể hiện HttpContext
đã định cấu hình.
Kiểm thử tích hợp dịch vụ gRPC
Kiểm thử tích hợp đánh giá các thành phần của ứng dụng ở cấp độ rộng hơn so với kiểm thử đơn vị. Ứng dụng gRPC được lưu trữ trong TestServer, một máy chủ thử nghiệm trong bộ nhớ của gói Microsoft.AspNetCore.TestHost.
Thư viện kiểm thử đơn vị khởi động ứng dụng gRPC và sau đó các dịch vụ gRPC được kiểm thử bằng ứng dụng khách gRPC.
Code mẫu chứa cơ sở hạ tầng để thực hiện thử nghiệm tích hợp:
- Lớp
GrpcTestFixture<TStartup>
định cấu hình máy chủ ASP.NET Core và khởi động ứng dụng gRPC trong máy chủ thử nghiệm trong bộ nhớ. - Lớp
IntegrationTestBase
là kiểu cơ sở mà các bài kiểm thử tích hợp kế thừa. Nó chứa trạng thái cố định và các API để tạo ứng dụng khách gRPC để gọi ứng dụng gRPC.
[Fact]
public async Task SayHelloUnaryTest()
{
// Arrange
var client = new Tester.TesterClient(Channel);
// Act
var response = await client.SayHelloUnaryAsync(new HelloRequest { Name = "Joe" });
// Assert
Assert.Equal("Hello Joe", response.Message);
}
Bài kiểm thử tích hợp trên:
- Tạo ứng dụng khách gRPC bằng cách sử dụng kênh do
IntegrationTestBase
. Kiểu này đã được bao gồm trong code mẫu. - Gọi phương thức
SayHelloUnary
bằng ứng dụng khách gRPC. - Xác nhận dịch vụ trả về message trả lời dự kiến.
Chèn phần phụ thuộc mô phỏng
Sử dụng ConfigureWebHost
trên thiết bị cố định để ghi đè các phần phụ thuộc. Ghi đè các phần phụ thuộc rất hữu ích khi phần phụ thuộc bên ngoài không có sẵn trong môi trường thử nghiệm. Ví dụ: ứng dụng sử dụng cổng thanh toán bên ngoài không được gọi phần phụ thuộc bên ngoài khi thực hiện kiểm thử. Thay vào đó, hãy sử dụng một cổng mô phỏng để kiểm thử.
public MockedGreeterServiceTests(GrpcTestFixture<Startup> fixture,
ITestOutputHelper outputHelper) : base(fixture, outputHelper)
{
var mockGreeter = new Mock<IGreeter>();
mockGreeter.Setup(
m => m.Greet(It.IsAny<string>())).Returns((string s) =>
{
if (string.IsNullOrEmpty(s))
{
throw new ArgumentException("Name not provided.");
}
return $"Test {s}";
});
Fixture.ConfigureWebHost(builder =>
{
builder.ConfigureServices(
services => services.AddSingleton(mockGreeter.Object));
});
}
[Fact]
public async Task SayHelloUnaryTest_MockGreeter_Success()
{
// Arrange
var client = new Tester.TesterClient(Channel);
// Act
var response = await client.SayHelloUnaryAsync(
new HelloRequest { Name = "Joe" });
// Assert
Assert.Equal("Test Joe", response.Message);
}
Bài kiểm thử tích hợp trên:
- Trong hàm tạo (MockedGreeterServiceTests) của lớp kiểm thử:
- Mô phỏng
IGreeter
sử dụng Moq. - Ghi đè
IGreeter
đã đăng ký bằng dependency injection bằng cách sử dụngConfigureWebHost
.
- Mô phỏng
- Gọi phương thức
SayHelloUnary
bằng ứng dụng khách gRPC. - Xác nhận message trả lời dự kiến dựa trên thể hiện
IGreeter
mô phỏng.
Tài nguyên bổ sung
- Test dịch vụ gRPC với Postman hoặc gRPCurl trong ASP.NET Core
- Giả lập máy khách gRPC trong các thử nghiệm