Интеграционные тесты ASP .NET Core WebAPI 8 не работают с gRPCC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Интеграционные тесты ASP .NET Core WebAPI 8 не работают с gRPC

Сообщение Anonymous »

У меня есть WebAPI, написанный на .NET Core, этот API настроен для работы с Http1 и Http2

Код: Выделить всё

"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http1AndHttp2"
}
}
Моя проблема в том, что я не могу выполнить к нему какие-либо вызовы gRPC (обычные HTTP-вызовы работают), и я понятия не имею, как с этим справиться (ошибка в соединении >)
Причина использования HTTP2 заключается в возможности выполнять вызовы gRPC, я использую библиотеки protobuf-net, и все работает нормально, когда бы я ни запускал свой API, Я получаю пару URL-адресов запуска (http и https), и вызовы HTTP и gRPC работают.
Моя основная проблема заключается в том, что я не могу настроить свое интеграционное тестовое приспособление, чтобы оно работало.
Прежде всего позвольте мне показать вам мой Program.cs

Код: Выделить всё

var builder = WebApplication.CreateBuilder(args);
ServiceRegistration.ConfigureServices(builder, "AdcTrains", "adc-trains",
containerBuilderAdditionalActions:
containerBuilder =>
{

},
additionalMiddlewareActions: webApp =>
{
if (webApp.Environment.IsDevelopment())
{
webApp.MapCodeFirstGrpcReflectionService();
}

webApp.MapGrpcService();
},

additionalPostBuildBehavior: async webApp =>
{
// write unit tests / integration tests rather than this
var tenantIdString = "19d74b3c-2955-4667-9bc5-15d67212469e";

var multitenantService = webApp.Services.GetRequiredService();
var tenantScope = multitenantService.GetTenantScope(tenantIdString);
var resolverService = tenantScope.Resolve();
var trainGrpcService = resolverService.ResolveService(Guid.Parse(tenantIdString));
});

/// 
/// Not to be removed, used for the testing project
/// 
public partial class Program { }
Это довольно пусто, причина в том, что я использую написанную мной базовую библиотеку, которая поддерживает различные функции, такие как gRPC, Redis, RabbitMQ и т. д.
В нем я сначала включаю свой код gRPC

Код: Выделить всё

  // this is actually exposing real grpc endpoints
services.AddCodeFirstGrpcReflection();

services.AddCodeFirstGrpc(config =>
{
config.ResponseCompressionLevel = System.IO.Compression.CompressionLevel.Optimal;
});
Я опубликовал верхний отрывок только для того, чтобы объяснить, как работает мой API и как я разрешаю свои службы grpc (просто чтобы убедиться, что они инициализируются правильно, поскольку интеграционное тестирование не работает), а теперь вернемся в проект интеграционного тестирования.
Это вся моя WebApplicationFactory, написанная согласно документации

Код: Выделить всё

/// 
/// This is the base fixture for all the integration tests
/// https://learn.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-8.0
/// 
public class CustomWebApplicationFactory : WebApplicationFactory, IAsyncLifetime where TProgram : class
{
protected const string TenantId = "19d74b3c-2955-4667-9bc5-15d67212469e";
// this will be initialized in InitializeAsync
public HttpClient HttpClient = default!;

public HubConnection WebHubConnection { get; set; }
public HubConnection RequestHubConnection { get; set; }

protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.UseEnvironment("Test");

builder
//.UseTestServer()
.ConfigureServices(services =>
{
services.AddCodeFirstGrpcReflection();

services.AddCodeFirstGrpc(config =>
{
config.ResponseCompressionLevel = System.IO.Compression.CompressionLevel.Optimal;
config.EnableDetailedErrors = true;
});
})
.UseUrls("https://localhost:7034")
.ConfigureKestrel(k =>
{
k.ConfigureEndpointDefaults(lo => lo.Protocols = HttpProtocols.Http1AndHttp2);
k.ListenAnyIP(7034, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
});

})
.Configure(app =>
{
app.UseRouting();

app.UseEndpoints(endpoints =>
{
endpoints.MapGrpcService();
});
});
}

#region IAsyncLifetime
public async Task InitializeAsync()
{
HttpClient = CreateClient();

var configuration = Services.GetRequiredService();
var testConfiguration = configuration.GetSection("TestConfiguration");

var httpClient = new HttpClient();

var tokenResponse = await httpClient.RequestPasswordTokenAsync(new PasswordTokenRequest
{
Address = testConfiguration.GetValue("Ids"),
ClientId = testConfiguration.GetValue("ClientId")!,
Scope = testConfiguration.GetValue("Scope"),

UserName = testConfiguration.GetValue("UserName")!,
Password = testConfiguration.GetValue("Password")!
});

HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokenResponse.AccessToken);
HttpClient.DefaultRequestHeaders.Add("tenantId", TenantId);

// SignalR hookup
var hubConnectionService = new HubConnectionService(configuration);

var cancellationTokenSource = new CancellationTokenSource(15000);

// Front-end conn
WebHubConnection = await hubConnectionService.HubInitialize("webNotifications", tokenResponse.AccessToken, cancellationTokenSource.Token);

// Simulating the OBS system, basically in front-end == obs just so we can test easily
RequestHubConnection = await hubConnectionService.HubInitialize("trainRequest", tokenResponse.AccessToken, cancellationTokenSource.Token);

if (WebHubConnection.ConnectionId is null)
throw new Exception("Error at connecting to SignalR");

Log.Information("Hub connectionId: {hubConnectionId}", WebHubConnection.ConnectionId);
}

/// 
/// Logout
/// 
/// 
public async Task DisposeAsync()
{
var configuration = Services.GetRequiredService();
var testConfiguration = configuration.GetSection("TestConfiguration");

await HttpClient.RevokeTokenAsync(new TokenRevocationRequest
{
Token = HttpClient.DefaultRequestHeaders.Authorization!.Parameter,
Address = testConfiguration.GetValue("Ids")
});
}
#endregion
}
И, наконец, приспособление:

Код: Выделить всё

public class TrainGrpcConfigFixture : IClassFixture
{
private readonly CustomWebApplicationFactory _factory;

public TrainGrpcConfigFixture(CustomWebApplicationFactory factory)
=> _factory = factory;

[Fact]
public async Task Get_NvrSet_Response_ExpectData()
{
// Arrange
var grpcResolver = _factory.Services.GetService(typeof(IGrpcResolverService)) as IGrpcResolverService;
var trainGrpcService = grpcResolver.ResolveService();
var response = await trainGrpcService.GetNvrSetResponseAsync(new TrainConfig.Grpc.Models.Dtos.NvrSet.Requests.NvrSetRequest() { TrainId = 8 });
}
}
Всякий раз, когда он пытается подключиться, он терпит неудачу, соединение отказано...
Поэтому я предполагаю, что по какой-то причине мой WebApi не запускается с определенным портом, как я пытался (7034), и он просто отвергает меня.
Я исчерпал все свои попытки, прежде чем писать здесь, я нашел несколько образцов, но они довольно старые и, кажется, со всего мира 2019~, пытался включить их сюда, но они не увенчались успехом.... поэтому я просто остановился на официальном документе для .NET 8, который не охватывает многое, связанное с go gRPC.

Подробнее здесь: https://stackoverflow.com/questions/788 ... -with-grpc
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»