在测试中模拟 gRPC 客户端
测试是构建稳定且可维护的软件的一个重要方面。 编写高质量测试的一部分是删除外部依赖项。 本文讨论如何在测试中使用模拟 gRPC 客户端来删除对外部服务器的 gRPC 调用。
可测试客户端应用示例
若要演示客户端应用测试,请在示例应用中查看以下类型。
Worker
是调用 gRPC 服务器的 BackgroundService。
public class Worker : BackgroundService
{
private readonly Tester.TesterClient _client;
private readonly IGreetRepository _greetRepository;
public Worker(Tester.TesterClient client, IGreetRepository greetRepository)
{
_client = client;
_greetRepository = greetRepository;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
var count = 0;
while (!stoppingToken.IsCancellationRequested)
{
count++;
var reply = await _client.SayHelloUnaryAsync(
new HelloRequest { Name = $"Worker {count}" });
_greetRepository.SaveGreeting(reply.Message);
await Task.Delay(1000, stoppingToken);
}
}
}
前面的类型:
- 遵循显式依赖关系原则。
TesterClient
是在生成过程中基于 test.proto 文件由工具包 Grpc.Tools 自动生成的。- 期望依赖关系注入 (DI) 提供
TesterClient
和IGreetRepository
的实例。 应用配置为使用 gRPC 客户端工厂创建TesterClient
。 - 可以使用 mock 对象框架(如 Moq)对模拟
IGreetRepository
服务和TesterClient
客户端进行测试。 模拟对象是由一组预先确定的用于测试的属性和方法行为的对象。 有关详细信息,请参阅 ASP.NET Core 中的集成测试。
有关 Grpc.Tools 自动生成的 C# 资产的详细信息,请参阅使用 C# 的 gRPC 服务:生成的 C# 资产。
模拟 gRPC 客户端
gRPC 客户端是从 .proto
文件生成的具体客户端类型。 具体 gRPC 客户端具有转换为 .proto
文件中 gRPC 服务的方法。 例如,名为 Greeter
的服务生成 GreeterClient
类型(包含调用服务的方法)。
模拟框架可以模拟 gRPC 客户端类型。 当模拟客户端传递给该类型时,测试将使用模拟方法,而不是将 gRPC 调用发送给服务器。
[Fact]
public async Task Greeting_Success_RepositoryCalled()
{
// Arrange
var mockRepository = new Mock<IGreetRepository>();
var mockCall = CallHelpers.CreateAsyncUnaryCall(new HelloReply { Message = "Test" });
var mockClient = new Mock<Tester.TesterClient>();
mockClient
.Setup(m => m.SayHelloUnaryAsync(
It.IsAny<HelloRequest>(), null, null, CancellationToken.None))
.Returns(mockCall);
var worker = new Worker(mockClient.Object, mockRepository.Object);
// Act
await worker.StartAsync(CancellationToken.None);
// Assert
mockRepository.Verify(v => v.SaveGreeting("Test"));
}
前面的单元测试:
- 使用 Moq 模拟
IGreetRepository
和TesterClient
。 - 启动辅助角色。
- 确认
SaveGreeting
是使用模拟的TesterClient
返回的问候消息调用的。
其他资源
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈