mirror of
https://github.com/meysamhadeli/booking-microservices.git
synced 2026-04-18 09:52:11 +08:00
.
This commit is contained in:
parent
efcf745edc
commit
1be144f005
@ -1,12 +1,17 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Booking.Data;
|
using Booking.Data;
|
||||||
|
using BuildingBlocks.Contracts.Grpc;
|
||||||
using BuildingBlocks.Core.Model;
|
using BuildingBlocks.Core.Model;
|
||||||
using BuildingBlocks.MassTransit;
|
using BuildingBlocks.MassTransit;
|
||||||
using BuildingBlocks.Mongo;
|
using BuildingBlocks.Mongo;
|
||||||
using BuildingBlocks.Web;
|
using BuildingBlocks.Web;
|
||||||
using Grpc.Net.Client;
|
using Grpc.Net.Client;
|
||||||
|
using Integration.Test.Fakes;
|
||||||
|
using MagicOnion;
|
||||||
using MassTransit;
|
using MassTransit;
|
||||||
using MassTransit.Testing;
|
using MassTransit.Testing;
|
||||||
using MediatR;
|
using MediatR;
|
||||||
@ -35,12 +40,11 @@ public class FixtureCollection : ICollectionFixture<IntegrationTestFixture>
|
|||||||
public class IntegrationTestFixture : IAsyncLifetime
|
public class IntegrationTestFixture : IAsyncLifetime
|
||||||
{
|
{
|
||||||
private WebApplicationFactory<Program> _factory;
|
private WebApplicationFactory<Program> _factory;
|
||||||
public Checkpoint Checkpoint { get; set; }
|
private Checkpoint _checkpoint;
|
||||||
|
|
||||||
private MongoDbRunner _mongoRunner;
|
private MongoDbRunner _mongoRunner;
|
||||||
public Action<IServiceCollection>? TestRegistrationServices { get; set; }
|
private IServiceProvider _serviceProvider;
|
||||||
public IServiceProvider ServiceProvider => _factory.Services;
|
private Action<IServiceCollection>? _testRegistrationServices;
|
||||||
public IConfiguration Configuration => _factory.Services.GetRequiredService<IConfiguration>();
|
private IConfiguration _configuration;
|
||||||
public HttpClient HttpClient => _factory.CreateClient();
|
public HttpClient HttpClient => _factory.CreateClient();
|
||||||
public ITestHarness TestHarness => CreateHarness();
|
public ITestHarness TestHarness => CreateHarness();
|
||||||
public GrpcChannel Channel => CreateChannel();
|
public GrpcChannel Channel => CreateChannel();
|
||||||
@ -53,68 +57,78 @@ public class IntegrationTestFixture : IAsyncLifetime
|
|||||||
builder.UseEnvironment("test");
|
builder.UseEnvironment("test");
|
||||||
builder.ConfigureServices(services =>
|
builder.ConfigureServices(services =>
|
||||||
{
|
{
|
||||||
services.ReplaceSingleton(AddHttpContextAccessorMock);
|
_testRegistrationServices?.Invoke(services);
|
||||||
TestRegistrationServices?.Invoke(services);
|
|
||||||
services.AddMassTransitTestHarness(x =>
|
|
||||||
{
|
|
||||||
x.UsingRabbitMq((context, cfg) =>
|
|
||||||
{
|
|
||||||
var rabbitMqOptions = services.GetOptions<RabbitMqOptions>("RabbitMq");
|
|
||||||
var host = rabbitMqOptions.HostName;
|
|
||||||
|
|
||||||
cfg.Host(host, h =>
|
|
||||||
{
|
|
||||||
h.Username(rabbitMqOptions.UserName);
|
|
||||||
h.Password(rabbitMqOptions.Password);
|
|
||||||
});
|
|
||||||
cfg.ConfigureEndpoints(context);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
Checkpoint = new Checkpoint {TablesToIgnore = new[] {"__EFMigrationsHistory"}};
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// _mongoRunner = MongoDbRunner.Start();
|
RegisterServices(services =>
|
||||||
// var mongoOptions = _factory.Services.GetRequiredService<IOptions<MongoOptions>>();
|
{
|
||||||
// if (mongoOptions is not null)
|
MockFlightGrpcServices(services);
|
||||||
// mongoOptions.Value.ConnectionString = _mongoRunner.ConnectionString;
|
MockPassengerGrpcServices(services);
|
||||||
|
services.ReplaceSingleton(AddHttpContextAccessorMock);
|
||||||
|
services.AddMassTransitTestHarness(x =>
|
||||||
|
{
|
||||||
|
x.UsingRabbitMq((context, cfg) =>
|
||||||
|
{
|
||||||
|
var rabbitMqOptions = services.GetOptions<RabbitMqOptions>("RabbitMq");
|
||||||
|
var host = rabbitMqOptions.HostName;
|
||||||
|
|
||||||
|
cfg.Host(host, h =>
|
||||||
|
{
|
||||||
|
h.Username(rabbitMqOptions.UserName);
|
||||||
|
h.Password(rabbitMqOptions.Password);
|
||||||
|
});
|
||||||
|
cfg.ConfigureEndpoints(context);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
_serviceProvider = _factory.Services;
|
||||||
|
_configuration = _factory.Services.GetRequiredService<IConfiguration>();
|
||||||
|
|
||||||
|
_checkpoint = new Checkpoint {TablesToIgnore = new[] {"__EFMigrationsHistory"}};
|
||||||
|
|
||||||
|
_mongoRunner = MongoDbRunner.Start();
|
||||||
|
var mongoOptions = _factory.Services.GetRequiredService<IOptions<MongoOptions>>();
|
||||||
|
if (mongoOptions.Value.ConnectionString != null)
|
||||||
|
mongoOptions.Value.ConnectionString = _mongoRunner.ConnectionString;
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RegisterServices(Action<IServiceCollection> services) => _testRegistrationServices = services;
|
||||||
|
|
||||||
public virtual async Task DisposeAsync()
|
public virtual async Task DisposeAsync()
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(Configuration?.GetConnectionString("DefaultConnection")))
|
if (!string.IsNullOrEmpty(_configuration?.GetConnectionString("DefaultConnection")))
|
||||||
await Checkpoint.Reset(Configuration?.GetConnectionString("DefaultConnection"));
|
await _checkpoint.Reset(_configuration?.GetConnectionString("DefaultConnection"));
|
||||||
|
|
||||||
await _factory.DisposeAsync();
|
await _factory.DisposeAsync();
|
||||||
|
_mongoRunner.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ref: https://github.com/trbenning/serilog-sinks-xunit
|
// ref: https://github.com/trbenning/serilog-sinks-xunit
|
||||||
public ILogger CreateLogger(ITestOutputHelper output)
|
public ILogger CreateLogger(ITestOutputHelper output)
|
||||||
{
|
{
|
||||||
if (output != null)
|
if (output != null)
|
||||||
|
{
|
||||||
return new LoggerConfiguration()
|
return new LoggerConfiguration()
|
||||||
.WriteTo.TestOutput(output)
|
.WriteTo.TestOutput(output)
|
||||||
.CreateLogger();
|
.CreateLogger();
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegisterTestServices(Action<IServiceCollection> services)
|
|
||||||
{
|
|
||||||
TestRegistrationServices = services;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task ExecuteScopeAsync(Func<IServiceProvider, Task> action)
|
public async Task ExecuteScopeAsync(Func<IServiceProvider, Task> action)
|
||||||
{
|
{
|
||||||
using var scope = ServiceProvider.CreateScope();
|
using var scope = _serviceProvider.CreateScope();
|
||||||
await action(scope.ServiceProvider);
|
await action(scope.ServiceProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<T> ExecuteScopeAsync<T>(Func<IServiceProvider, Task<T>> action)
|
public async Task<T> ExecuteScopeAsync<T>(Func<IServiceProvider, Task<T>> action)
|
||||||
{
|
{
|
||||||
using var scope = ServiceProvider.CreateScope();
|
using var scope = _serviceProvider.CreateScope();
|
||||||
|
|
||||||
var result = await action(scope.ServiceProvider);
|
var result = await action(scope.ServiceProvider);
|
||||||
|
|
||||||
@ -245,7 +259,7 @@ public class IntegrationTestFixture : IAsyncLifetime
|
|||||||
|
|
||||||
private ITestHarness CreateHarness()
|
private ITestHarness CreateHarness()
|
||||||
{
|
{
|
||||||
var harness = ServiceProvider.GetTestHarness();
|
var harness = _serviceProvider.GetTestHarness();
|
||||||
harness.Start().GetAwaiter().GetResult();
|
harness.Start().GetAwaiter().GetResult();
|
||||||
return harness;
|
return harness;
|
||||||
}
|
}
|
||||||
@ -266,4 +280,36 @@ public class IntegrationTestFixture : IAsyncLifetime
|
|||||||
|
|
||||||
return httpContextAccessorMock;
|
return httpContextAccessorMock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void MockPassengerGrpcServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.Replace(ServiceDescriptor.Singleton(x =>
|
||||||
|
{
|
||||||
|
var mock = Substitute.For<IPassengerGrpcService>();
|
||||||
|
mock.GetById(Arg.Any<long>())
|
||||||
|
.Returns(new UnaryResult<PassengerResponseDto>(new FakePassengerResponseDto().Generate()));
|
||||||
|
|
||||||
|
return mock;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MockFlightGrpcServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.Replace(ServiceDescriptor.Singleton(x =>
|
||||||
|
{
|
||||||
|
var mock = Substitute.For<IFlightGrpcService>();
|
||||||
|
|
||||||
|
mock.GetById(Arg.Any<long>())
|
||||||
|
.Returns(new UnaryResult<FlightResponseDto>(Task.FromResult(new FakeFlightResponseDto().Generate())));
|
||||||
|
|
||||||
|
mock.GetAvailableSeats(Arg.Any<long>())
|
||||||
|
.Returns(
|
||||||
|
new UnaryResult<IEnumerable<SeatResponseDto>>(Task.FromResult(FakeSeatsResponseDto.Generate())));
|
||||||
|
|
||||||
|
mock.ReserveSeat(new FakeReserveSeatRequestDto().Generate())
|
||||||
|
.Returns(new UnaryResult<SeatResponseDto>(Task.FromResult(FakeSeatsResponseDto.Generate().First())));
|
||||||
|
|
||||||
|
return mock;
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,14 +2,10 @@
|
|||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BuildingBlocks.Core.Model;
|
using BuildingBlocks.Core.Model;
|
||||||
using BuildingBlocks.EFCore;
|
|
||||||
using BuildingBlocks.MassTransit;
|
using BuildingBlocks.MassTransit;
|
||||||
using BuildingBlocks.MessageProcessor;
|
|
||||||
using BuildingBlocks.Mongo;
|
using BuildingBlocks.Mongo;
|
||||||
using BuildingBlocks.Web;
|
using BuildingBlocks.Web;
|
||||||
using DotNetCore.CAP.MongoDB;
|
|
||||||
using Flight.Data;
|
using Flight.Data;
|
||||||
using FluentAssertions.Common;
|
|
||||||
using Grpc.Net.Client;
|
using Grpc.Net.Client;
|
||||||
using MassTransit;
|
using MassTransit;
|
||||||
using MassTransit.Testing;
|
using MassTransit.Testing;
|
||||||
@ -17,11 +13,8 @@ using MediatR;
|
|||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc.Testing;
|
using Microsoft.AspNetCore.Mvc.Testing;
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
|
||||||
using Microsoft.Extensions.Hosting;
|
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Mongo2Go;
|
using Mongo2Go;
|
||||||
using NSubstitute;
|
using NSubstitute;
|
||||||
@ -39,17 +32,76 @@ public class FixtureCollection : ICollectionFixture<IntegrationTestFixture>
|
|||||||
|
|
||||||
public class IntegrationTestFixture : IAsyncLifetime
|
public class IntegrationTestFixture : IAsyncLifetime
|
||||||
{
|
{
|
||||||
|
private Checkpoint _checkpoint;
|
||||||
|
private IConfiguration _configuration;
|
||||||
private WebApplicationFactory<Program> _factory;
|
private WebApplicationFactory<Program> _factory;
|
||||||
|
|
||||||
private MongoDbRunner _mongoRunner;
|
private MongoDbRunner _mongoRunner;
|
||||||
public Checkpoint Checkpoint { get; set; }
|
private IServiceProvider _serviceProvider;
|
||||||
public Action<IServiceCollection>? TestRegistrationServices { get; set; }
|
private Action<IServiceCollection>? _testRegistrationServices;
|
||||||
public IServiceProvider ServiceProvider => _factory.Services;
|
|
||||||
public IConfiguration Configuration => _factory.Services.GetRequiredService<IConfiguration>();
|
|
||||||
public HttpClient HttpClient => _factory.CreateClient();
|
public HttpClient HttpClient => _factory.CreateClient();
|
||||||
public ITestHarness TestHarness => CreateHarness();
|
public ITestHarness TestHarness => CreateHarness();
|
||||||
public GrpcChannel Channel => CreateChannel();
|
public GrpcChannel Channel => CreateChannel();
|
||||||
|
|
||||||
|
|
||||||
|
public virtual Task InitializeAsync()
|
||||||
|
{
|
||||||
|
_factory = new WebApplicationFactory<Program>()
|
||||||
|
.WithWebHostBuilder(builder =>
|
||||||
|
{
|
||||||
|
builder.UseEnvironment("test");
|
||||||
|
builder.ConfigureServices(services =>
|
||||||
|
{
|
||||||
|
_testRegistrationServices?.Invoke(services);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
RegisterServices(services =>
|
||||||
|
{
|
||||||
|
services.ReplaceSingleton(AddHttpContextAccessorMock);
|
||||||
|
services.AddMassTransitTestHarness(x =>
|
||||||
|
{
|
||||||
|
x.UsingRabbitMq((context, cfg) =>
|
||||||
|
{
|
||||||
|
var rabbitMqOptions = services.GetOptions<RabbitMqOptions>("RabbitMq");
|
||||||
|
var host = rabbitMqOptions.HostName;
|
||||||
|
|
||||||
|
cfg.Host(host, h =>
|
||||||
|
{
|
||||||
|
h.Username(rabbitMqOptions.UserName);
|
||||||
|
h.Password(rabbitMqOptions.Password);
|
||||||
|
});
|
||||||
|
cfg.ConfigureEndpoints(context);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
_serviceProvider = _factory.Services;
|
||||||
|
_configuration = _factory.Services.GetRequiredService<IConfiguration>();
|
||||||
|
|
||||||
|
_checkpoint = new Checkpoint {TablesToIgnore = new[] {"__EFMigrationsHistory"}};
|
||||||
|
|
||||||
|
_mongoRunner = MongoDbRunner.Start();
|
||||||
|
var mongoOptions = _factory.Services.GetRequiredService<IOptions<MongoOptions>>();
|
||||||
|
if (mongoOptions.Value.ConnectionString != null)
|
||||||
|
mongoOptions.Value.ConnectionString = _mongoRunner.ConnectionString;
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task DisposeAsync()
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(_configuration?.GetConnectionString("DefaultConnection")))
|
||||||
|
await _checkpoint.Reset(_configuration?.GetConnectionString("DefaultConnection"));
|
||||||
|
|
||||||
|
await _factory.DisposeAsync();
|
||||||
|
_mongoRunner.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegisterServices(Action<IServiceCollection> services)
|
||||||
|
{
|
||||||
|
_testRegistrationServices = services;
|
||||||
|
}
|
||||||
|
|
||||||
// ref: https://github.com/trbenning/serilog-sinks-xunit
|
// ref: https://github.com/trbenning/serilog-sinks-xunit
|
||||||
public ILogger CreateLogger(ITestOutputHelper output)
|
public ILogger CreateLogger(ITestOutputHelper output)
|
||||||
{
|
{
|
||||||
@ -63,61 +115,15 @@ public class IntegrationTestFixture : IAsyncLifetime
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegisterTestServices(Action<IServiceCollection> services) => TestRegistrationServices = services;
|
|
||||||
|
|
||||||
public virtual Task InitializeAsync()
|
|
||||||
{
|
|
||||||
_factory = new WebApplicationFactory<Program>()
|
|
||||||
.WithWebHostBuilder(builder =>
|
|
||||||
{
|
|
||||||
builder.UseEnvironment("test");
|
|
||||||
builder.ConfigureServices(services =>
|
|
||||||
{
|
|
||||||
services.AddMassTransitTestHarness(x =>
|
|
||||||
{
|
|
||||||
x.UsingRabbitMq((context, cfg) =>
|
|
||||||
{
|
|
||||||
var rabbitMqOptions = services.GetOptions<RabbitMqOptions>("RabbitMq");
|
|
||||||
var host = rabbitMqOptions.HostName;
|
|
||||||
|
|
||||||
cfg.Host(host, h =>
|
|
||||||
{
|
|
||||||
h.Username(rabbitMqOptions.UserName);
|
|
||||||
h.Password(rabbitMqOptions.Password);
|
|
||||||
});
|
|
||||||
cfg.ConfigureEndpoints(context);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
Checkpoint = new Checkpoint {TablesToIgnore = new[] {"__EFMigrationsHistory"}};
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
_mongoRunner = MongoDbRunner.Start();
|
|
||||||
var mongoOptions = _factory.Services.GetRequiredService<IOptions<MongoOptions>>();
|
|
||||||
mongoOptions.Value.ConnectionString = _mongoRunner.ConnectionString;
|
|
||||||
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task DisposeAsync()
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(Configuration?.GetConnectionString("DefaultConnection")))
|
|
||||||
await Checkpoint.Reset(Configuration?.GetConnectionString("DefaultConnection"));
|
|
||||||
|
|
||||||
await _factory.DisposeAsync();
|
|
||||||
_mongoRunner.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task ExecuteScopeAsync(Func<IServiceProvider, Task> action)
|
public async Task ExecuteScopeAsync(Func<IServiceProvider, Task> action)
|
||||||
{
|
{
|
||||||
using var scope = ServiceProvider.CreateScope();
|
using var scope = _serviceProvider.CreateScope();
|
||||||
await action(scope.ServiceProvider);
|
await action(scope.ServiceProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<T> ExecuteScopeAsync<T>(Func<IServiceProvider, Task<T>> action)
|
public async Task<T> ExecuteScopeAsync<T>(Func<IServiceProvider, Task<T>> action)
|
||||||
{
|
{
|
||||||
using var scope = ServiceProvider.CreateScope();
|
using var scope = _serviceProvider.CreateScope();
|
||||||
|
|
||||||
var result = await action(scope.ServiceProvider);
|
var result = await action(scope.ServiceProvider);
|
||||||
|
|
||||||
@ -248,7 +254,7 @@ public class IntegrationTestFixture : IAsyncLifetime
|
|||||||
|
|
||||||
private ITestHarness CreateHarness()
|
private ITestHarness CreateHarness()
|
||||||
{
|
{
|
||||||
var harness = ServiceProvider.GetTestHarness();
|
var harness = _serviceProvider.GetTestHarness();
|
||||||
harness.Start().GetAwaiter().GetResult();
|
harness.Start().GetAwaiter().GetResult();
|
||||||
return harness;
|
return harness;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ using System.Net.Http;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BuildingBlocks.Core.Model;
|
using BuildingBlocks.Core.Model;
|
||||||
using BuildingBlocks.MassTransit;
|
using BuildingBlocks.MassTransit;
|
||||||
|
using BuildingBlocks.Mongo;
|
||||||
using BuildingBlocks.Web;
|
using BuildingBlocks.Web;
|
||||||
using Grpc.Net.Client;
|
using Grpc.Net.Client;
|
||||||
using Identity.Data;
|
using Identity.Data;
|
||||||
@ -14,8 +15,8 @@ using Microsoft.AspNetCore.Http;
|
|||||||
using Microsoft.AspNetCore.Mvc.Testing;
|
using Microsoft.AspNetCore.Mvc.Testing;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
using Microsoft.Extensions.Options;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Mongo2Go;
|
||||||
using NSubstitute;
|
using NSubstitute;
|
||||||
using Respawn;
|
using Respawn;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
@ -31,15 +32,17 @@ public class FixtureCollection : ICollectionFixture<IntegrationTestFixture>
|
|||||||
|
|
||||||
public class IntegrationTestFixture : IAsyncLifetime
|
public class IntegrationTestFixture : IAsyncLifetime
|
||||||
{
|
{
|
||||||
|
private Checkpoint _checkpoint;
|
||||||
|
private IConfiguration _configuration;
|
||||||
private WebApplicationFactory<Program> _factory;
|
private WebApplicationFactory<Program> _factory;
|
||||||
public Checkpoint Checkpoint { get; set; }
|
private MongoDbRunner _mongoRunner;
|
||||||
public Action<IServiceCollection>? TestRegistrationServices { get; set; }
|
private IServiceProvider _serviceProvider;
|
||||||
public IServiceProvider ServiceProvider => _factory.Services;
|
private Action<IServiceCollection>? _testRegistrationServices;
|
||||||
public IConfiguration Configuration => _factory.Services.GetRequiredService<IConfiguration>();
|
|
||||||
public HttpClient HttpClient => _factory.CreateClient();
|
public HttpClient HttpClient => _factory.CreateClient();
|
||||||
public ITestHarness TestHarness => CreateHarness();
|
public ITestHarness TestHarness => CreateHarness();
|
||||||
public GrpcChannel Channel => CreateChannel();
|
public GrpcChannel Channel => CreateChannel();
|
||||||
|
|
||||||
|
|
||||||
public virtual Task InitializeAsync()
|
public virtual Task InitializeAsync()
|
||||||
{
|
{
|
||||||
_factory = new WebApplicationFactory<Program>()
|
_factory = new WebApplicationFactory<Program>()
|
||||||
@ -48,66 +51,79 @@ public class IntegrationTestFixture : IAsyncLifetime
|
|||||||
builder.UseEnvironment("test");
|
builder.UseEnvironment("test");
|
||||||
builder.ConfigureServices(services =>
|
builder.ConfigureServices(services =>
|
||||||
{
|
{
|
||||||
services.ReplaceSingleton(AddHttpContextAccessorMock);
|
_testRegistrationServices?.Invoke(services);
|
||||||
TestRegistrationServices?.Invoke(services);
|
|
||||||
services.AddMassTransitTestHarness(x =>
|
|
||||||
{
|
|
||||||
x.UsingRabbitMq((context, cfg) =>
|
|
||||||
{
|
|
||||||
var rabbitMqOptions = services.GetOptions<RabbitMqOptions>("RabbitMq");
|
|
||||||
var host = rabbitMqOptions.HostName;
|
|
||||||
|
|
||||||
cfg.Host(host, h =>
|
|
||||||
{
|
|
||||||
h.Username(rabbitMqOptions.UserName);
|
|
||||||
h.Password(rabbitMqOptions.Password);
|
|
||||||
});
|
|
||||||
cfg.ConfigureEndpoints(context);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
Checkpoint = new Checkpoint {TablesToIgnore = new[] {"__EFMigrationsHistory"}};
|
|
||||||
|
|
||||||
TestRegistrationServices?.Invoke(services);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
RegisterServices(services =>
|
||||||
|
{
|
||||||
|
services.ReplaceSingleton(AddHttpContextAccessorMock);
|
||||||
|
services.AddMassTransitTestHarness(x =>
|
||||||
|
{
|
||||||
|
x.UsingRabbitMq((context, cfg) =>
|
||||||
|
{
|
||||||
|
var rabbitMqOptions = services.GetOptions<RabbitMqOptions>("RabbitMq");
|
||||||
|
var host = rabbitMqOptions.HostName;
|
||||||
|
|
||||||
|
cfg.Host(host, h =>
|
||||||
|
{
|
||||||
|
h.Username(rabbitMqOptions.UserName);
|
||||||
|
h.Password(rabbitMqOptions.Password);
|
||||||
|
});
|
||||||
|
cfg.ConfigureEndpoints(context);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
_serviceProvider = _factory.Services;
|
||||||
|
_configuration = _factory.Services.GetRequiredService<IConfiguration>();
|
||||||
|
|
||||||
|
_checkpoint = new Checkpoint {TablesToIgnore = new[] {"__EFMigrationsHistory"}};
|
||||||
|
|
||||||
|
_mongoRunner = MongoDbRunner.Start();
|
||||||
|
var mongoOptions = _factory.Services.GetRequiredService<IOptions<MongoOptions>>();
|
||||||
|
if (mongoOptions.Value.ConnectionString != null)
|
||||||
|
mongoOptions.Value.ConnectionString = _mongoRunner.ConnectionString;
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task DisposeAsync()
|
public virtual async Task DisposeAsync()
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(Configuration?.GetConnectionString("DefaultConnection")))
|
if (!string.IsNullOrEmpty(_configuration?.GetConnectionString("DefaultConnection")))
|
||||||
await Checkpoint.Reset(Configuration?.GetConnectionString("DefaultConnection"));
|
await _checkpoint.Reset(_configuration?.GetConnectionString("DefaultConnection"));
|
||||||
|
|
||||||
await _factory.DisposeAsync();
|
await _factory.DisposeAsync();
|
||||||
|
_mongoRunner.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegisterServices(Action<IServiceCollection> services)
|
||||||
|
{
|
||||||
|
_testRegistrationServices = services;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ref: https://github.com/trbenning/serilog-sinks-xunit
|
// ref: https://github.com/trbenning/serilog-sinks-xunit
|
||||||
public ILogger CreateLogger(ITestOutputHelper output)
|
public ILogger CreateLogger(ITestOutputHelper output)
|
||||||
{
|
{
|
||||||
if (output != null)
|
if (output != null)
|
||||||
|
{
|
||||||
return new LoggerConfiguration()
|
return new LoggerConfiguration()
|
||||||
.WriteTo.TestOutput(output)
|
.WriteTo.TestOutput(output)
|
||||||
.CreateLogger();
|
.CreateLogger();
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegisterTestServices(Action<IServiceCollection> services)
|
|
||||||
{
|
|
||||||
TestRegistrationServices = services;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task ExecuteScopeAsync(Func<IServiceProvider, Task> action)
|
public async Task ExecuteScopeAsync(Func<IServiceProvider, Task> action)
|
||||||
{
|
{
|
||||||
using var scope = ServiceProvider.CreateScope();
|
using var scope = _serviceProvider.CreateScope();
|
||||||
await action(scope.ServiceProvider);
|
await action(scope.ServiceProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<T> ExecuteScopeAsync<T>(Func<IServiceProvider, Task<T>> action)
|
public async Task<T> ExecuteScopeAsync<T>(Func<IServiceProvider, Task<T>> action)
|
||||||
{
|
{
|
||||||
using var scope = ServiceProvider.CreateScope();
|
using var scope = _serviceProvider.CreateScope();
|
||||||
|
|
||||||
var result = await action(scope.ServiceProvider);
|
var result = await action(scope.ServiceProvider);
|
||||||
|
|
||||||
@ -238,7 +254,7 @@ public class IntegrationTestFixture : IAsyncLifetime
|
|||||||
|
|
||||||
private ITestHarness CreateHarness()
|
private ITestHarness CreateHarness()
|
||||||
{
|
{
|
||||||
var harness = ServiceProvider.GetTestHarness();
|
var harness = _serviceProvider.GetTestHarness();
|
||||||
harness.Start().GetAwaiter().GetResult();
|
harness.Start().GetAwaiter().GetResult();
|
||||||
return harness;
|
return harness;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@ public sealed class PassengerDbContext : AppDbContextBase
|
|||||||
{
|
{
|
||||||
public const string DefaultSchema = "dbo";
|
public const string DefaultSchema = "dbo";
|
||||||
|
|
||||||
public PassengerDbContext(DbContextOptions options, IHttpContextAccessor httpContextAccessor) : base(options, httpContextAccessor)
|
public PassengerDbContext(DbContextOptions<PassengerDbContext> options, IHttpContextAccessor httpContextAccessor) : base(options, httpContextAccessor)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ using System.Net.Http;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BuildingBlocks.Core.Model;
|
using BuildingBlocks.Core.Model;
|
||||||
using BuildingBlocks.MassTransit;
|
using BuildingBlocks.MassTransit;
|
||||||
|
using BuildingBlocks.Mongo;
|
||||||
using BuildingBlocks.Web;
|
using BuildingBlocks.Web;
|
||||||
using Grpc.Net.Client;
|
using Grpc.Net.Client;
|
||||||
using MassTransit;
|
using MassTransit;
|
||||||
@ -13,8 +14,8 @@ using Microsoft.AspNetCore.Http;
|
|||||||
using Microsoft.AspNetCore.Mvc.Testing;
|
using Microsoft.AspNetCore.Mvc.Testing;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
using Microsoft.Extensions.Options;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Mongo2Go;
|
||||||
using NSubstitute;
|
using NSubstitute;
|
||||||
using Passenger.Data;
|
using Passenger.Data;
|
||||||
using Respawn;
|
using Respawn;
|
||||||
@ -31,15 +32,17 @@ public class FixtureCollection : ICollectionFixture<IntegrationTestFixture>
|
|||||||
|
|
||||||
public class IntegrationTestFixture : IAsyncLifetime
|
public class IntegrationTestFixture : IAsyncLifetime
|
||||||
{
|
{
|
||||||
|
private Checkpoint _checkpoint;
|
||||||
|
private IConfiguration _configuration;
|
||||||
private WebApplicationFactory<Program> _factory;
|
private WebApplicationFactory<Program> _factory;
|
||||||
public Checkpoint Checkpoint { get; set; }
|
private MongoDbRunner _mongoRunner;
|
||||||
public Action<IServiceCollection>? TestRegistrationServices { get; set; }
|
private IServiceProvider _serviceProvider;
|
||||||
public IServiceProvider ServiceProvider => _factory.Services;
|
private Action<IServiceCollection>? _testRegistrationServices;
|
||||||
public IConfiguration Configuration => _factory.Services.GetRequiredService<IConfiguration>();
|
|
||||||
public HttpClient HttpClient => _factory.CreateClient();
|
public HttpClient HttpClient => _factory.CreateClient();
|
||||||
public ITestHarness TestHarness => CreateHarness();
|
public ITestHarness TestHarness => CreateHarness();
|
||||||
public GrpcChannel Channel => CreateChannel();
|
public GrpcChannel Channel => CreateChannel();
|
||||||
|
|
||||||
|
|
||||||
public virtual Task InitializeAsync()
|
public virtual Task InitializeAsync()
|
||||||
{
|
{
|
||||||
_factory = new WebApplicationFactory<Program>()
|
_factory = new WebApplicationFactory<Program>()
|
||||||
@ -48,66 +51,79 @@ public class IntegrationTestFixture : IAsyncLifetime
|
|||||||
builder.UseEnvironment("test");
|
builder.UseEnvironment("test");
|
||||||
builder.ConfigureServices(services =>
|
builder.ConfigureServices(services =>
|
||||||
{
|
{
|
||||||
services.ReplaceSingleton(AddHttpContextAccessorMock);
|
_testRegistrationServices?.Invoke(services);
|
||||||
TestRegistrationServices?.Invoke(services);
|
|
||||||
services.AddMassTransitTestHarness(x =>
|
|
||||||
{
|
|
||||||
x.UsingRabbitMq((context, cfg) =>
|
|
||||||
{
|
|
||||||
var rabbitMqOptions = services.GetOptions<RabbitMqOptions>("RabbitMq");
|
|
||||||
var host = rabbitMqOptions.HostName;
|
|
||||||
|
|
||||||
cfg.Host(host, h =>
|
|
||||||
{
|
|
||||||
h.Username(rabbitMqOptions.UserName);
|
|
||||||
h.Password(rabbitMqOptions.Password);
|
|
||||||
});
|
|
||||||
cfg.ConfigureEndpoints(context);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
Checkpoint = new Checkpoint {TablesToIgnore = new[] {"__EFMigrationsHistory"}};
|
|
||||||
|
|
||||||
TestRegistrationServices?.Invoke(services);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
RegisterServices(services =>
|
||||||
|
{
|
||||||
|
services.ReplaceSingleton(AddHttpContextAccessorMock);
|
||||||
|
services.AddMassTransitTestHarness(x =>
|
||||||
|
{
|
||||||
|
x.UsingRabbitMq((context, cfg) =>
|
||||||
|
{
|
||||||
|
var rabbitMqOptions = services.GetOptions<RabbitMqOptions>("RabbitMq");
|
||||||
|
var host = rabbitMqOptions.HostName;
|
||||||
|
|
||||||
|
cfg.Host(host, h =>
|
||||||
|
{
|
||||||
|
h.Username(rabbitMqOptions.UserName);
|
||||||
|
h.Password(rabbitMqOptions.Password);
|
||||||
|
});
|
||||||
|
cfg.ConfigureEndpoints(context);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
_serviceProvider = _factory.Services;
|
||||||
|
_configuration = _factory.Services.GetRequiredService<IConfiguration>();
|
||||||
|
|
||||||
|
_checkpoint = new Checkpoint {TablesToIgnore = new[] {"__EFMigrationsHistory"}};
|
||||||
|
|
||||||
|
_mongoRunner = MongoDbRunner.Start();
|
||||||
|
var mongoOptions = _factory.Services.GetRequiredService<IOptions<MongoOptions>>();
|
||||||
|
if (mongoOptions.Value.ConnectionString != null)
|
||||||
|
mongoOptions.Value.ConnectionString = _mongoRunner.ConnectionString;
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task DisposeAsync()
|
public virtual async Task DisposeAsync()
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(Configuration?.GetConnectionString("DefaultConnection")))
|
if (!string.IsNullOrEmpty(_configuration?.GetConnectionString("DefaultConnection")))
|
||||||
await Checkpoint.Reset(Configuration?.GetConnectionString("DefaultConnection"));
|
await _checkpoint.Reset(_configuration?.GetConnectionString("DefaultConnection"));
|
||||||
|
|
||||||
await _factory.DisposeAsync();
|
await _factory.DisposeAsync();
|
||||||
|
_mongoRunner.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegisterServices(Action<IServiceCollection> services)
|
||||||
|
{
|
||||||
|
_testRegistrationServices = services;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ref: https://github.com/trbenning/serilog-sinks-xunit
|
// ref: https://github.com/trbenning/serilog-sinks-xunit
|
||||||
public ILogger CreateLogger(ITestOutputHelper output)
|
public ILogger CreateLogger(ITestOutputHelper output)
|
||||||
{
|
{
|
||||||
if (output != null)
|
if (output != null)
|
||||||
|
{
|
||||||
return new LoggerConfiguration()
|
return new LoggerConfiguration()
|
||||||
.WriteTo.TestOutput(output)
|
.WriteTo.TestOutput(output)
|
||||||
.CreateLogger();
|
.CreateLogger();
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegisterTestServices(Action<IServiceCollection> services)
|
|
||||||
{
|
|
||||||
TestRegistrationServices = services;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task ExecuteScopeAsync(Func<IServiceProvider, Task> action)
|
public async Task ExecuteScopeAsync(Func<IServiceProvider, Task> action)
|
||||||
{
|
{
|
||||||
using var scope = ServiceProvider.CreateScope();
|
using var scope = _serviceProvider.CreateScope();
|
||||||
await action(scope.ServiceProvider);
|
await action(scope.ServiceProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<T> ExecuteScopeAsync<T>(Func<IServiceProvider, Task<T>> action)
|
public async Task<T> ExecuteScopeAsync<T>(Func<IServiceProvider, Task<T>> action)
|
||||||
{
|
{
|
||||||
using var scope = ServiceProvider.CreateScope();
|
using var scope = _serviceProvider.CreateScope();
|
||||||
|
|
||||||
var result = await action(scope.ServiceProvider);
|
var result = await action(scope.ServiceProvider);
|
||||||
|
|
||||||
@ -238,7 +254,7 @@ public class IntegrationTestFixture : IAsyncLifetime
|
|||||||
|
|
||||||
private ITestHarness CreateHarness()
|
private ITestHarness CreateHarness()
|
||||||
{
|
{
|
||||||
var harness = ServiceProvider.GetTestHarness();
|
var harness = _serviceProvider.GetTestHarness();
|
||||||
harness.Start().GetAwaiter().GetResult();
|
harness.Start().GetAwaiter().GetResult();
|
||||||
return harness;
|
return harness;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user