fix: fix ci failed for tests

This commit is contained in:
Meysam Hadeli 2026-02-21 22:00:57 +03:30
parent 7f9cf8b922
commit 0f66c14299
4 changed files with 96 additions and 86 deletions

View File

@ -133,14 +133,10 @@ public class TestFixture<TEntryPoint> : IAsyncLifetime
{ {
CancellationTokenSource = new CancellationTokenSource(); CancellationTokenSource = new CancellationTokenSource();
await StartTestContainerAsync(); await StartTestContainerAsync();
await TestHarness.Start();
} }
public async Task DisposeAsync() public async Task DisposeAsync()
{ {
await TestHarness.Stop();
await StopTestContainerAsync(); await StopTestContainerAsync();
await _factory.DisposeAsync(); await _factory.DisposeAsync();
await CancellationTokenSource.CancelAsync(); await CancellationTokenSource.CancelAsync();
@ -277,14 +273,11 @@ public class TestFixture<TEntryPoint> : IAsyncLifetime
MongoDbTestContainer = TestContainers.MongoTestContainer(); MongoDbTestContainer = TestContainers.MongoTestContainer();
EventStoreDbTestContainer = TestContainers.EventStoreTestContainer(); EventStoreDbTestContainer = TestContainers.EventStoreTestContainer();
await Task.WhenAll( await MongoDbTestContainer.StartAsync();
MongoDbTestContainer.StartAsync(), await PostgresTestcontainer.StartAsync();
PostgresTestcontainer.StartAsync(), await PostgresPersistTestContainer.StartAsync();
PostgresPersistTestContainer.StartAsync(),
EventStoreDbTestContainer.StartAsync()
);
await RabbitMqTestContainer.StartAsync(); await RabbitMqTestContainer.StartAsync();
await EventStoreDbTestContainer.StartAsync();
} }
private async Task StopTestContainerAsync() private async Task StopTestContainerAsync()

View File

@ -13,9 +13,12 @@ public static class GrpcClientExtensions
public static IServiceCollection AddGrpcClients(this IServiceCollection services) public static IServiceCollection AddGrpcClients(this IServiceCollection services)
{ {
var grpcOptions = services.GetOptions<GrpcOptions>("Grpc"); var grpcOptions = services.GetOptions<GrpcOptions>("Grpc");
var resilienceOptions = services.GetOptions<HttpStandardResilienceOptions>(nameof(HttpStandardResilienceOptions)); var resilienceOptions = services.GetOptions<HttpStandardResilienceOptions>(
nameof(HttpStandardResilienceOptions)
);
services.AddGrpcClient<FlightGrpcService.FlightGrpcServiceClient>(o => services
.AddGrpcClient<FlightGrpcService.FlightGrpcServiceClient>(o =>
{ {
o.Address = new Uri(grpcOptions.FlightAddress); o.Address = new Uri(grpcOptions.FlightAddress);
}) })
@ -25,54 +28,37 @@ public static class GrpcClientExtensions
{ {
var timeSpan = TimeSpan.FromMinutes(1); var timeSpan = TimeSpan.FromMinutes(1);
options.AddRetry( options.AddRetry(new HttpRetryStrategyOptions { MaxRetryAttempts = 3 });
new HttpRetryStrategyOptions
{
MaxRetryAttempts = 3,
});
options.AddCircuitBreaker( options.AddCircuitBreaker(
new HttpCircuitBreakerStrategyOptions new HttpCircuitBreakerStrategyOptions { SamplingDuration = timeSpan * 2 }
{ );
SamplingDuration = timeSpan * 2,
});
options.AddTimeout( options.AddTimeout(new HttpTimeoutStrategyOptions { Timeout = timeSpan * 3 });
new HttpTimeoutStrategyOptions }
{ );
Timeout = timeSpan * 3,
});
});
services.AddGrpcClient<PassengerGrpcService.PassengerGrpcServiceClient>(o => services
{ .AddGrpcClient<PassengerGrpcService.PassengerGrpcServiceClient>(o =>
o.Address = new Uri(grpcOptions.PassengerAddress);
})
.AddResilienceHandler(
"grpc-passenger-resilience",
options =>
{ {
var timeSpan = TimeSpan.FromMinutes(1); o.Address = new Uri(grpcOptions.PassengerAddress);
})
.AddResilienceHandler(
"grpc-passenger-resilience",
options =>
{
var timeSpan = TimeSpan.FromMinutes(1);
options.AddRetry( options.AddRetry(new HttpRetryStrategyOptions { MaxRetryAttempts = 3 });
new HttpRetryStrategyOptions
{
MaxRetryAttempts = 3,
});
options.AddCircuitBreaker( options.AddCircuitBreaker(
new HttpCircuitBreakerStrategyOptions new HttpCircuitBreakerStrategyOptions { SamplingDuration = timeSpan * 2 }
{ );
SamplingDuration = timeSpan * 2,
});
options.AddTimeout( options.AddTimeout(new HttpTimeoutStrategyOptions { Timeout = timeSpan * 3 });
new HttpTimeoutStrategyOptions }
{ );
Timeout = timeSpan * 3,
});
});
return services; return services;
} }
} }

View File

@ -19,10 +19,8 @@ namespace Integration.Test.Booking.Features
{ {
public class CreateBookingTests : BookingIntegrationTestBase public class CreateBookingTests : BookingIntegrationTestBase
{ {
public CreateBookingTests(TestReadFixture<Program, BookingReadDbContext> integrationTestFixture) : base( public CreateBookingTests(TestReadFixture<Program, BookingReadDbContext> integrationTestFixture)
integrationTestFixture) : base(integrationTestFixture) { }
{
}
protected override void RegisterTestsServices(IServiceCollection services) protected override void RegisterTestsServices(IServiceCollection services)
{ {
@ -45,41 +43,76 @@ namespace Integration.Test.Booking.Features
(await Fixture.WaitForPublishing<BookingCreated>()).Should().Be(true); (await Fixture.WaitForPublishing<BookingCreated>()).Should().Be(true);
} }
private void MockPassengerGrpcServices(IServiceCollection services) private void MockPassengerGrpcServices(IServiceCollection services)
{ {
services.Replace(ServiceDescriptor.Singleton(x => services.Replace(
{ ServiceDescriptor.Singleton(x =>
var mockPassenger = Substitute.For<PassengerGrpcService.PassengerGrpcServiceClient>(); {
var mockPassenger = Substitute.For<PassengerGrpcService.PassengerGrpcServiceClient>();
mockPassenger.GetByIdAsync(Arg.Any<Passenger.GetByIdRequest>()) mockPassenger
.Returns(TestCalls.AsyncUnaryCall(Task.FromResult(FakePassengerResponse.Generate()), .GetByIdAsync(Arg.Any<Passenger.GetByIdRequest>())
Task.FromResult(new Metadata()), () => Status.DefaultSuccess, () => new Metadata(), () => { })); .Returns(
TestCalls.AsyncUnaryCall(
Task.FromResult(FakePassengerResponse.Generate()),
Task.FromResult(new Metadata()),
() => Status.DefaultSuccess,
() => new Metadata(),
() => { }
)
);
return mockPassenger; return mockPassenger;
})); })
);
} }
private void MockFlightGrpcServices(IServiceCollection services) private void MockFlightGrpcServices(IServiceCollection services)
{ {
services.Replace(ServiceDescriptor.Singleton(x => services.Replace(
{ ServiceDescriptor.Singleton(x =>
var mockFlight = Substitute.For<FlightGrpcService.FlightGrpcServiceClient>(); {
var mockFlight = Substitute.For<FlightGrpcService.FlightGrpcServiceClient>();
mockFlight.GetByIdAsync(Arg.Any<GetByIdRequest>()) mockFlight
.Returns(TestCalls.AsyncUnaryCall(Task.FromResult(FakeFlightResponse.Generate()), .GetByIdAsync(Arg.Any<GetByIdRequest>())
Task.FromResult(new Metadata()), () => Status.DefaultSuccess, () => new Metadata(), () => { })); .Returns(
TestCalls.AsyncUnaryCall(
Task.FromResult(FakeFlightResponse.Generate()),
Task.FromResult(new Metadata()),
() => Status.DefaultSuccess,
() => new Metadata(),
() => { }
)
);
mockFlight.GetAvailableSeatsAsync(Arg.Any<GetAvailableSeatsRequest>()) mockFlight
.Returns(TestCalls.AsyncUnaryCall(Task.FromResult(FakeGetAvailableSeatsResponse.Generate()), .GetAvailableSeatsAsync(Arg.Any<GetAvailableSeatsRequest>())
Task.FromResult(new Metadata()), () => Status.DefaultSuccess, () => new Metadata(), () => { })); .Returns(
TestCalls.AsyncUnaryCall(
Task.FromResult(FakeGetAvailableSeatsResponse.Generate()),
Task.FromResult(new Metadata()),
() => Status.DefaultSuccess,
() => new Metadata(),
() => { }
)
);
mockFlight.ReserveSeatAsync(Arg.Any<ReserveSeatRequest>()) mockFlight
.Returns(TestCalls.AsyncUnaryCall(Task.FromResult(FakeReserveSeatResponse.Generate()), .ReserveSeatAsync(Arg.Any<ReserveSeatRequest>())
Task.FromResult(new Metadata()), () => Status.DefaultSuccess, () => new Metadata(), () => { })); .Returns(
TestCalls.AsyncUnaryCall(
Task.FromResult(FakeReserveSeatResponse.Generate()),
Task.FromResult(new Metadata()),
() => Status.DefaultSuccess,
() => new Metadata(),
() => { }
)
);
return mockFlight; return mockFlight;
})); })
);
} }
} }
} }

View File

@ -1,4 +1,3 @@
using Booking.Api;
using Booking.Data; using Booking.Data;
using BuildingBlocks.TestBase; using BuildingBlocks.TestBase;
using Xunit; using Xunit;
@ -8,13 +7,12 @@ namespace Integration.Test;
[Collection(IntegrationTestCollection.Name)] [Collection(IntegrationTestCollection.Name)]
public class BookingIntegrationTestBase : TestReadBase<Program, BookingReadDbContext> public class BookingIntegrationTestBase : TestReadBase<Program, BookingReadDbContext>
{ {
public BookingIntegrationTestBase(TestReadFixture<Program, BookingReadDbContext> integrationTestFixture) : base(integrationTestFixture) public BookingIntegrationTestBase(TestReadFixture<Program, BookingReadDbContext> integrationTestFixture)
{ : base(integrationTestFixture) { }
}
} }
[CollectionDefinition(Name)] [CollectionDefinition(Name)]
public class IntegrationTestCollection : ICollectionFixture<TestReadFixture<Program, BookingReadDbContext>> public class IntegrationTestCollection : ICollectionFixture<TestReadFixture<Program, BookingReadDbContext>>
{ {
public const string Name = "Booking Integration Test"; public const string Name = "Booking Integration Test";
} }