mirror of
https://github.com/alex289/CleanArchitecture.git
synced 2025-06-30 02:31:08 +00:00
feat: Add rabbit and redis to integration tests
This commit is contained in:
parent
dca566cbf6
commit
4a8c102d00
@ -72,7 +72,7 @@ builder.Services.AddLogging(x => x.AddSimpleConsole(console =>
|
||||
console.IncludeScopes = true;
|
||||
}));
|
||||
|
||||
if (builder.Environment.IsProduction())
|
||||
if (builder.Environment.IsProduction() || !string.IsNullOrWhiteSpace(builder.Configuration["RedisHostName"]))
|
||||
{
|
||||
builder.Services.AddStackExchangeRedisCache(options =>
|
||||
{
|
||||
@ -95,12 +95,8 @@ using (var scope = app.Services.CreateScope())
|
||||
var domainStoreDbContext = services.GetRequiredService<DomainNotificationStoreDbContext>();
|
||||
|
||||
appDbContext.EnsureMigrationsApplied();
|
||||
|
||||
if (app.Environment.EnvironmentName != "Integration")
|
||||
{
|
||||
storeDbContext.EnsureMigrationsApplied();
|
||||
domainStoreDbContext.EnsureMigrationsApplied();
|
||||
}
|
||||
storeDbContext.EnsureMigrationsApplied();
|
||||
domainStoreDbContext.EnsureMigrationsApplied();
|
||||
}
|
||||
|
||||
if (app.Environment.IsDevelopment())
|
||||
|
@ -13,6 +13,7 @@
|
||||
"Audience": "CleanArchitectureClient",
|
||||
"Secret": "sD3v061gf8BxXgmxcHssasjdlkasjd87439284)@#(*"
|
||||
},
|
||||
"RedisHostName": "",
|
||||
"RabbitMQ": {
|
||||
"Host": "localhost",
|
||||
"Username": "guest",
|
||||
|
@ -5,6 +5,7 @@
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"RedisHostName": "",
|
||||
"RabbitMQ": {
|
||||
"Host": "localhost",
|
||||
"Username": "guest",
|
||||
|
@ -5,7 +5,7 @@ using Xunit;
|
||||
|
||||
namespace CleanArchitecture.IntegrationTests.Fixtures;
|
||||
|
||||
public sealed class DatabaseFixture : IAsyncLifetime
|
||||
public sealed class AccessorFixture : IAsyncLifetime
|
||||
{
|
||||
public static string TestRunDbName { get; } = $"CleanArchitecture-Integration-{Guid.NewGuid()}";
|
||||
|
||||
@ -13,11 +13,23 @@ public sealed class DatabaseFixture : IAsyncLifetime
|
||||
{
|
||||
var db = DatabaseAccessor.GetOrCreateAsync(TestRunDbName);
|
||||
await db.DisposeAsync();
|
||||
|
||||
var redis = RedisAccessor.GetOrCreateAsync();
|
||||
await redis.DisposeAsync();
|
||||
|
||||
var rabbit = RabbitmqAccessor.GetOrCreateAsync();
|
||||
await rabbit.DisposeAsync();
|
||||
}
|
||||
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
var db = DatabaseAccessor.GetOrCreateAsync(TestRunDbName);
|
||||
await db.InitializeAsync();
|
||||
|
||||
var redis = RedisAccessor.GetOrCreateAsync();
|
||||
await redis.InitializeAsync();
|
||||
|
||||
var rabbit = RabbitmqAccessor.GetOrCreateAsync();
|
||||
await rabbit.InitializeAsync();
|
||||
}
|
||||
}
|
@ -22,7 +22,7 @@ public class TestFixtureBase : IAsyncLifetime
|
||||
Factory = new CleanArchitectureWebApplicationFactory(
|
||||
RegisterCustomServicesHandler,
|
||||
useTestAuthentication,
|
||||
DatabaseFixture.TestRunDbName);
|
||||
AccessorFixture.TestRunDbName);
|
||||
|
||||
ServerClient = Factory.CreateClient();
|
||||
ServerClient.Timeout = TimeSpan.FromMinutes(5);
|
||||
|
@ -40,18 +40,31 @@ public sealed class CleanArchitectureWebApplicationFactory : WebApplicationFacto
|
||||
|
||||
base.ConfigureWebHost(builder);
|
||||
|
||||
var configuration = new ConfigurationBuilder()
|
||||
.Build();
|
||||
|
||||
builder.ConfigureAppConfiguration(configurationBuilder =>
|
||||
{
|
||||
configurationBuilder.AddEnvironmentVariables();
|
||||
|
||||
var accessor = DatabaseAccessor.GetOrCreateAsync(_instanceDatabaseName);
|
||||
var dbAccessor = DatabaseAccessor.GetOrCreateAsync(_instanceDatabaseName);
|
||||
var redisAccessor = RedisAccessor.GetOrCreateAsync();
|
||||
var rabbitAccessor = RabbitmqAccessor.GetOrCreateAsync();
|
||||
|
||||
// Overwrite default connection string to our test instance db
|
||||
// Overwrite default connection strings
|
||||
configurationBuilder.AddInMemoryCollection([
|
||||
new KeyValuePair<string, string?>(
|
||||
"ConnectionStrings:DefaultConnection",
|
||||
accessor.GetConnectionString())
|
||||
dbAccessor.GetConnectionString()),
|
||||
new KeyValuePair<string, string?>(
|
||||
"RedisHostName",
|
||||
redisAccessor.GetConnectionString()),
|
||||
new KeyValuePair<string, string?>(
|
||||
"RabbitMQ:Host",
|
||||
rabbitAccessor.GetConnectionString())
|
||||
]);
|
||||
|
||||
configuration = configurationBuilder.Build();
|
||||
});
|
||||
|
||||
builder.ConfigureServices(services =>
|
||||
@ -70,8 +83,14 @@ public sealed class CleanArchitectureWebApplicationFactory : WebApplicationFacto
|
||||
using var scope = sp.CreateScope();
|
||||
var scopedServices = scope.ServiceProvider;
|
||||
|
||||
var accessor = DatabaseAccessor.GetOrCreateAsync(_instanceDatabaseName);
|
||||
var applicationDbContext = accessor.CreateDatabase(scopedServices);
|
||||
var dbAccessor = DatabaseAccessor.GetOrCreateAsync(_instanceDatabaseName);
|
||||
dbAccessor.CreateDatabase(scopedServices);
|
||||
|
||||
var redisAccessor = RedisAccessor.GetOrCreateAsync();
|
||||
redisAccessor.RegisterRedis(services, configuration);
|
||||
|
||||
var rabbitAccessor = RabbitmqAccessor.GetOrCreateAsync();
|
||||
rabbitAccessor.RegisterRabbitmq(services, configuration);
|
||||
|
||||
_registerCustomServicesHandler?.Invoke(services, sp, scopedServices);
|
||||
});
|
||||
@ -85,7 +104,13 @@ public sealed class CleanArchitectureWebApplicationFactory : WebApplicationFacto
|
||||
|
||||
public override async ValueTask DisposeAsync()
|
||||
{
|
||||
var accessor = DatabaseAccessor.GetOrCreateAsync(_instanceDatabaseName);
|
||||
await accessor.DisposeAsync();
|
||||
var dbAccessor = DatabaseAccessor.GetOrCreateAsync(_instanceDatabaseName);
|
||||
await dbAccessor.DisposeAsync();
|
||||
|
||||
var redisAccessor = RedisAccessor.GetOrCreateAsync();
|
||||
await redisAccessor.DisposeAsync();
|
||||
|
||||
var rabbitAccessor = RabbitmqAccessor.GetOrCreateAsync();
|
||||
await rabbitAccessor.DisposeAsync();
|
||||
}
|
||||
}
|
@ -18,7 +18,7 @@ public sealed class DatabaseAccessor
|
||||
private bool _databaseCreated = false;
|
||||
private readonly object _databaseCreationLock = new();
|
||||
|
||||
private const string _dbPassword = "12345678##as";
|
||||
private const string _dbPassword = "234#AD224fD#ss";
|
||||
private static readonly MsSqlContainer s_dbContainer = new MsSqlBuilder()
|
||||
.WithPassword(_dbPassword)
|
||||
.WithPortBinding(1433)
|
||||
@ -61,6 +61,7 @@ public sealed class DatabaseAccessor
|
||||
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
// Reset the database to its original state
|
||||
var dropScript = $@"
|
||||
USE MASTER;
|
||||
|
||||
|
@ -0,0 +1,64 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using CleanArchitecture.Domain.Rabbitmq;
|
||||
using CleanArchitecture.Domain.Rabbitmq.Extensions;
|
||||
using Microsoft.Extensions.Caching.Distributed;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Testcontainers.RabbitMq;
|
||||
using RabbitMqConfiguration = CleanArchitecture.Domain.Rabbitmq.RabbitMqConfiguration;
|
||||
|
||||
namespace CleanArchitecture.IntegrationTests.Infrastructure;
|
||||
|
||||
public sealed class RabbitmqAccessor
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, RabbitmqAccessor> s_accessors = new();
|
||||
|
||||
private static readonly RabbitMqContainer s_rabbitContainer = new RabbitMqBuilder()
|
||||
.WithPortBinding(5672)
|
||||
.Build();
|
||||
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
await s_rabbitContainer.StartAsync();
|
||||
}
|
||||
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
await s_rabbitContainer.DisposeAsync();
|
||||
}
|
||||
|
||||
public string GetConnectionString()
|
||||
{
|
||||
return s_rabbitContainer.GetConnectionString();
|
||||
}
|
||||
|
||||
public void RegisterRabbitmq(IServiceCollection serviceCollection, IConfiguration configuration)
|
||||
{
|
||||
var rabbitService = serviceCollection.FirstOrDefault(x =>
|
||||
x.ServiceType == typeof(RabbitMqHandler));
|
||||
|
||||
if (rabbitService != null)
|
||||
{
|
||||
serviceCollection.Remove(rabbitService);
|
||||
}
|
||||
|
||||
var rabbitConfig = serviceCollection.FirstOrDefault(x =>
|
||||
x.ServiceType == typeof(RabbitMqConfiguration));
|
||||
|
||||
if (rabbitConfig != null)
|
||||
{
|
||||
serviceCollection.Remove(rabbitConfig);
|
||||
}
|
||||
|
||||
serviceCollection.AddRabbitMqHandler(
|
||||
configuration,
|
||||
"RabbitMQ");
|
||||
}
|
||||
|
||||
public static RabbitmqAccessor GetOrCreateAsync()
|
||||
{
|
||||
return s_accessors.GetOrAdd("rabbimq", _ => new RabbitmqAccessor());
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Caching.Distributed;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Testcontainers.Redis;
|
||||
|
||||
namespace CleanArchitecture.IntegrationTests.Infrastructure;
|
||||
|
||||
public sealed class RedisAccessor
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, RedisAccessor> s_accessors = new();
|
||||
|
||||
private static readonly RedisContainer s_redisContainer = new RedisBuilder()
|
||||
.WithPortBinding(6379)
|
||||
.Build();
|
||||
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
await s_redisContainer.StartAsync();
|
||||
}
|
||||
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
await s_redisContainer.DisposeAsync();
|
||||
}
|
||||
|
||||
public string GetConnectionString()
|
||||
{
|
||||
return s_redisContainer.GetConnectionString();
|
||||
}
|
||||
|
||||
public void RegisterRedis(IServiceCollection serviceCollection, IConfiguration configuration)
|
||||
{
|
||||
var distributedCache = serviceCollection.FirstOrDefault(x =>
|
||||
x.ServiceType == typeof(IDistributedCache));
|
||||
|
||||
if (distributedCache != null)
|
||||
{
|
||||
serviceCollection.Remove(distributedCache);
|
||||
}
|
||||
|
||||
serviceCollection.AddStackExchangeRedisCache(options =>
|
||||
{
|
||||
options.Configuration = configuration["RedisHostName"];
|
||||
options.InstanceName = "clean-architecture";
|
||||
});
|
||||
}
|
||||
|
||||
public static RedisAccessor GetOrCreateAsync()
|
||||
{
|
||||
return s_accessors.GetOrAdd("redis", _ => new RedisAccessor());
|
||||
}
|
||||
}
|
@ -5,6 +5,6 @@ namespace CleanArchitecture.IntegrationTests;
|
||||
|
||||
[CollectionDefinition("IntegrationTests", DisableParallelization = true)]
|
||||
public sealed class IntegrationTestsCollection :
|
||||
ICollectionFixture<DatabaseFixture>
|
||||
ICollectionFixture<AccessorFixture>
|
||||
{
|
||||
}
|
Loading…
Reference in New Issue
Block a user