次の方法で共有


テストで gRPC クライアントをモックする

作成者: James Newton-King

テストは、安定し、保守性に優れたソフトウェアを構築する上で重要な作業です。 高品質のテストの作成の一環として、外部依存関係を削除します。 この記事では、テストでモック 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 は、ビルド プロセス中に、ツール パッケージ Grpc.Tools によって、test.proto ファイルに基づいて自動的に生成されます。
  • 依存関係の挿入 (DI)TesterClientIGreetRepository のインスタンスを提供する必要があります。 このアプリは、gRPC クライアント ファクトリを使用して TesterClient を作成するように構成されています。
  • モック オブジェクト フレームワーク (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 を使用して、IGreetRepositoryTesterClient をモックします。
  • worker を開始します。
  • モックされた TesterClient が返すあいさつメッセージを使って SaveGreeting が呼び出されることを確認します。

その他のリソース