Compartilhar via


Cliente gRPC simulado em testes

Observação

Esta não é a versão mais recente deste artigo. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.

Aviso

Esta versão do ASP.NET Core não tem mais suporte. Para obter mais informações, confira .NET e a Política de Suporte do .NET Core. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.

Importante

Essas informações relacionam-se ao produto de pré-lançamento, que poderá ser substancialmente modificado antes do lançamento comercial. A Microsoft não oferece nenhuma garantia, explícita ou implícita, quanto às informações fornecidas aqui.

Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.

Por: James Newton-King

O teste é um aspecto importante da criação de software estável e de manutenção. Parte da gravação de testes de alta qualidade é a remoção de dependências externas. Este artigo discute o uso de clientes gRPC fictícios em testes para remover chamadas gRPC para servidores externos.

Exemplo de aplicativo cliente testável

Para demonstrar testes de aplicativo de cliente, examine o tipo a seguir no aplicativo de exemplo.

Exibir ou baixar código de exemplo (como baixar)

O Worker é um BackgroundService que faz chamadas para um servidor gRPC.

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);
        }
    }
}

O tipo anterior:

  • Segue o Princípio de Dependências Explícitas.
  • TesterClient é gerado automaticamente pelo pacote de ferramentas Grpc.Tools com base no arquivo test.proto, durante o processo de build.
  • Espera injeção de dependência (DI) para fornecer uma instância de TesterClient e IGreetRepository. O aplicativo está configurado para usar a fábrica de clientes gRPC a fim de criar TesterClient.
  • Pode ser testado com um serviço de IGreetRepository simulado e um cliente TesterClient usando uma estrutura de objeto simulada, como Moq. Um objeto fictício é um objeto fabricado com um conjunto predeterminado de comportamentos de propriedade e de método usado para teste. Para obter mais informações, confira Testes de integração no ASP.NET Core.

Para obter mais informações sobre os ativos C# gerados automaticamente pelo Grpc.Tools, confira Serviços gRPC com C#: ativos C# gerados.

Simular um cliente gRPC

Os clientes gRPC são tipos de cliente concretos gerados a partir de arquivos .proto. O cliente gRPC concreto tem métodos que se traduzem para o serviço gRPC no arquivo .proto. Por exemplo, um serviço chamado Greeter gera um tipo GreeterClient com métodos para chamar o serviço.

Uma estrutura de simulação pode simular um tipo de cliente gRPC. Quando um cliente simulado é passado para o tipo, o teste usa o método simulado em vez de enviar uma chamada gRPC para um servidor.

[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"));
}

O teste de unidade anterior:

  • Simula IGreetRepository e TesterClient usando Moq.
  • Inicia o trabalho.
  • Verifica se SaveGreeting é chamado com a mensagem de saudação retornada pelo TesterClient simulado.

Recursos adicionais