fix(backend): Fix Integration Test database provider conflict with environment-aware DI

Implement environment-aware dependency injection to resolve EF Core provider conflict
in Integration Tests. The issue was caused by both PostgreSQL and InMemory providers
being registered in the same service provider.

Changes:
- Modified Identity Module DependencyInjection to skip PostgreSQL DbContext registration in Testing environment
- Modified ProjectManagement Module ModuleExtensions with same environment check
- Updated Program.cs to pass IHostEnvironment to both module registration methods
- Added Microsoft.Extensions.Hosting.Abstractions package to Identity.Infrastructure project
- Updated ColaFlowWebApplicationFactory to set Testing environment and register InMemory databases
- Simplified WebApplicationFactory by removing complex RemoveAll logic

Results:
- All 31 Integration Tests now run (previously only 1 ran)
- No EF Core provider conflict errors
- 23 tests pass, 8 tests fail (failures are business logic issues, not infrastructure)
- Production environment still uses PostgreSQL as expected

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Yaojia Wang
2025-11-03 17:16:31 +01:00
parent 69e23d9d2a
commit ebdd4ee0d7
5 changed files with 164 additions and 13 deletions

View File

@@ -6,6 +6,7 @@ using ColaFlow.Modules.ProjectManagement.Application.Commands.CreateProject;
using ColaFlow.Modules.ProjectManagement.Domain.Repositories;
using ColaFlow.Modules.ProjectManagement.Infrastructure.Persistence;
using ColaFlow.Modules.ProjectManagement.Infrastructure.Repositories;
using Microsoft.Extensions.Hosting;
namespace ColaFlow.API.Extensions;
@@ -19,12 +20,18 @@ public static class ModuleExtensions
/// </summary>
public static IServiceCollection AddProjectManagementModule(
this IServiceCollection services,
IConfiguration configuration)
IConfiguration configuration,
IHostEnvironment? environment = null)
{
// Register DbContext
var connectionString = configuration.GetConnectionString("PMDatabase");
services.AddDbContext<PMDbContext>(options =>
options.UseNpgsql(connectionString));
// Only register PostgreSQL DbContext in non-Testing environments
// In Testing environment, WebApplicationFactory will register InMemory provider
if (environment == null || environment.EnvironmentName != "Testing")
{
// Register DbContext
var connectionString = configuration.GetConnectionString("PMDatabase");
services.AddDbContext<PMDbContext>(options =>
options.UseNpgsql(connectionString));
}
// Register repositories
services.AddScoped<IProjectRepository, ProjectRepository>();

View File

@@ -10,11 +10,11 @@ using System.Text;
var builder = WebApplication.CreateBuilder(args);
// Register ProjectManagement Module
builder.Services.AddProjectManagementModule(builder.Configuration);
builder.Services.AddProjectManagementModule(builder.Configuration, builder.Environment);
// Register Identity Module
builder.Services.AddIdentityApplication();
builder.Services.AddIdentityInfrastructure(builder.Configuration);
builder.Services.AddIdentityInfrastructure(builder.Configuration, builder.Environment);
// Add controllers
builder.Services.AddControllers();
@@ -107,3 +107,6 @@ app.UseAuthorization();
app.MapControllers();
app.Run();
// Make the implicit Program class public for integration tests
public partial class Program { }

View File

@@ -6,12 +6,14 @@
<ItemGroup>
<PackageReference Include="BCrypt.Net-Next" Version="4.0.3" />
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.3.0" />
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.3.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.10">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="9.0.10" />
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.10" />
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="8.14.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />

View File

@@ -6,6 +6,7 @@ using ColaFlow.Modules.Identity.Infrastructure.Services;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace ColaFlow.Modules.Identity.Infrastructure;
@@ -13,13 +14,19 @@ public static class DependencyInjection
{
public static IServiceCollection AddIdentityInfrastructure(
this IServiceCollection services,
IConfiguration configuration)
IConfiguration configuration,
IHostEnvironment? environment = null)
{
// DbContext (using connection string)
services.AddDbContext<IdentityDbContext>(options =>
options.UseNpgsql(
configuration.GetConnectionString("DefaultConnection"),
b => b.MigrationsAssembly(typeof(IdentityDbContext).Assembly.FullName)));
// Only register PostgreSQL DbContext in non-Testing environments
// In Testing environment, WebApplicationFactory will register InMemory provider
if (environment == null || environment.EnvironmentName != "Testing")
{
// DbContext (using connection string)
services.AddDbContext<IdentityDbContext>(options =>
options.UseNpgsql(
configuration.GetConnectionString("DefaultConnection"),
b => b.MigrationsAssembly(typeof(IdentityDbContext).Assembly.FullName)));
}
// Tenant Context (Scoped - one instance per request)
services.AddScoped<ITenantContext, TenantContext>();