Тестирование gRPC-сервисов
↑ 5.7 Тестирование интеграций · ← Предыдущая · → Следующая
Зачем это на собесе
Как проверять gRPC-сервис от unit-уровня до интеграции.
Объяснение
| Уровень | Как |
|---|---|
| Unit | вызвать метод сервиса напрямую с тестовым ServerCallContext |
| Интеграционный | WebApplicationFactory + GrpcChannel.ForAddress(client.BaseAddress, new GrpcChannelOptions { HttpHandler = server.CreateHandler() }) |
| Стриминг | чтение ResponseStream/запись RequestStream |
| Ошибки | RpcException.StatusCode |
public class OrdersGrpcTests(WebApplicationFactory<Program> f) : IClassFixture<WebApplicationFactory<Program>>
{
[Fact]
public async Task GetOrder_returns_NotFound_for_unknown_id()
{
var client = f.CreateDefaultClient();
using var channel = GrpcChannel.ForAddress(client.BaseAddress!, new GrpcChannelOptions { HttpClient = client });
var grpc = new OrderService.OrderServiceClient(channel);
var ex = await Assert.ThrowsAsync<RpcException>(() => grpc.GetOrderAsync(new GetOrderRequest { Id = Guid.NewGuid().ToString() }).ResponseAsync);
Assert.Equal(StatusCode.NotFound, ex.StatusCode);
}
}Unit-тест сервиса потребует тестовую реализацию ServerCallContext (например, из пакета Grpc.Core.Testing или собственная).
Проверяйте:
- Коды статусов и тексты ошибок, metadata.
- Deadline: сервер завершается по отмене токена.
- Стриминг: порядок, завершение, обработка отмены клиентом.
- Совместимость proto (
buf breaking).
Нюансы и подводные камни
- Для gRPC в тестах нужен HTTP/2:
TestServerего поддерживает; для реального Kestrel — настройка протокола. - Изолируйте состояние между тестами (данные, кэши).
- Тесты стриминга без таймаута зависают: задавайте
CancellationTokenSourceс лимитом. - Аутентификацию подменяйте так же, как в HTTP-тестах.
Практика
- Напишите интеграционные тесты unary и server streaming.
- Проверьте поведение при истечении deadline.
- Добавьте тест interceptor, преобразующего исключения в статусы.
Вопросы с ответами
Как тестировать gRPC без сети?
Через
WebApplicationFactoryи канал поверхTestServer-обработчика.
Как проверить ошибку?
Поймать
RpcExceptionи сравнитьStatusCode.