Sdílet prostřednictvím


Testování služeb gRPC v ASP.NET Core

Poznámka:

Toto není nejnovější verze tohoto článku. Aktuální verzi najdete v tomto článku ve verzi .NET 9.

Upozorňující

Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v zásadách podpory .NET a .NET Core. Aktuální verzi najdete v tomto článku ve verzi .NET 9.

Důležité

Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.

Aktuální verzi najdete v tomto článku ve verzi .NET 9.

Autor: James Newton-King

Testování je důležitým aspektem vytváření stabilního a udržovatelného softwaru. Tento článek popisuje, jak otestovat služby ASP.NET Core gRPC.

Existují tři běžné přístupy pro testování služeb gRPC:

  • Testování jednotek: Testování služeb gRPC přímo z knihovny testování jednotek.
  • Testování integrace: Aplikace gRPC je hostovaná v TestServertestovacím serveru v paměti z Microsoft.AspNetCore.TestHost balíčku. Služby gRPC jsou testovány jejich voláním pomocí klienta gRPC z knihovny testování jednotek.
  • Ruční testování: Testování serverů gRPC s ad hoc voláními Informace o používání nástrojů příkazového řádku a uživatelského rozhraní se službami gRPC naleznete v tématu Testování služeb gRPC s gRPCurl a gRPCui v ASP.NET Core.

V testování jednotek je zapojena pouze služba gRPC. Závislosti vložené do služby musí být napodobené. Při testování integrace je součástí testu služba gRPC a její pomocná infrastruktura. To zahrnuje spuštění aplikace, injektáž závislostí, směrování a ověřování a autorizaci.

Příklad testovatelné služby

Pokud chcete předvést testy služeb, projděte si následující službu v ukázkové aplikaci.

Zobrazení nebo stažení ukázkového kódu (postup stažení)

Vrátí TesterService pozdravy pomocí čtyř typů metod 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) });
        }
    }
}

Předchozí služba gRPC:

Služby gRPC pro testování jednotek

Knihovna testů jednotek může přímo testovat služby gRPC voláním jeho metod. Testy jednotek testuje izolovanou službu gRPC.

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

Předchozí test jednotek:

  • Napodobení IGreeter pomocí Moq.
  • Spustí metodu SayHelloUnary se zprávou požadavku a .ServerCallContext Všechny metody služby mají ServerCallContext argument. V tomto testu je k dispozici typ pomocí TestServerCallContext.Create() pomocné metody. Tato pomocná metoda je součástí ukázkového kódu.
  • Vytváří kontrolní výrazy:
    • Ověří, že název požadavku je předán .IGreeter
    • Služba vrátí očekávanou zprávu odpovědi.

HttpContext Testování jednotek v metodách gRPC

Metody gRPC mají přístup k požadavku HttpContext pomocí ServerCallContext.GetHttpContext metody rozšíření. Chcete-li testovat metodu, která používá HttpContext, musí být kontext nakonfigurován v testovacím nastavení. Pokud HttpContext není nakonfigurovaný, GetHttpContext vrátí hodnotu null.

Pokud chcete nakonfigurovat během testovacího HttpContext nastavení, vytvořte novou instanci a přidejte ji do ServerCallContext.UserState kolekce pomocí __HttpContext klíče.

var httpContext = new DefaultHttpContext();

var serverCallContext = TestServerCallContext.Create();
serverCallContext.UserState["__HttpContext"] = httpContext;

Spusťte metody služby s tímto kontextem volání pro použití nakonfigurované HttpContext instance.

Služby GRPC pro testování integrace

Integrační testy vyhodnocují komponenty aplikace na širší úrovni než testy jednotek. Aplikace gRPC je hostovaná na TestServertestovacím serveru v paměti z Microsoft.AspNetCore.TestHost balíčku.

Knihovna testů jednotek spustí aplikaci gRPC a služby gRPC se testují pomocí klienta gRPC.

Ukázkový kód obsahuje infrastrukturu, která umožňuje testování integrace:

  • Třída GrpcTestFixture<TStartup> nakonfiguruje hostitele ASP.NET Core a spustí aplikaci gRPC na testovacím serveru v paměti.
  • Třída IntegrationTestBase je základní typ, ze kterého dědí integrační testy. Obsahuje stav zařízení a rozhraní API pro vytvoření klienta gRPC pro volání aplikace 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);
}

Předchozí integrační test:

  • Vytvoří klienta gRPC pomocí kanálu, který IntegrationTestBaseposkytuje . Tento typ je součástí vzorového kódu.
  • Volá metodu SayHelloUnary pomocí klienta gRPC.
  • Služba vrátí očekávanou zprávu odpovědi.

Vložení napodobených závislostí

Pomocí ConfigureWebHost zařízení lze přepsat závislosti. Přepsání závislostí je užitečné, když není externí závislost v testovacím prostředí dostupná. Například aplikace, která používá externí platební bránu, by při provádění testů neměla volat externí závislost. Místo toho použijte pro test napodobenou bránu.

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

Předchozí integrační test:

  • V konstruktoru testovací třídyMockedGreeterServiceTests:
    • Napodobení IGreeter pomocí Moq.
    • Přepíše zaregistrovanou IGreeter injektáž závislostí pomocí ConfigureWebHost.
  • Volá metodu SayHelloUnary pomocí klienta gRPC.
  • Uplatní očekávanou zprávu odpovědi na základě instance napodobení IGreeter .

Další materiály