using AutoMapper; using ECMJobRunner.Domain.Interfaces; using ECMJobRunner.Infrastructure; using ECMJobRunner.Infrastructure.Data; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace ECMJobRunner.Tests.Infrastructure; /// /// Base test fixture with Dependency Injection and In-Memory Database /// Supports both .NET Framework 4.8 (EF6 with Effort) and .NET 8 (EF Core InMemory) /// public class TestFixture : IDisposable { private readonly IHost _host; private IServiceScope? _scope; public IServiceProvider Services => _scope?.ServiceProvider ?? _host.Services; public JobRunnerDbContext DbContext => Services.GetRequiredService(); public IMapper Mapper => Services.GetRequiredService(); public ICfgProfileRepository ProfileRepository => Services.GetRequiredService(); public IProfileSqlJobRepository SqlJobRepository => Services.GetRequiredService(); public IProfileHistoryRepository HistoryRepository => Services.GetRequiredService(); public TestFixture() { _host = Host.CreateDefaultBuilder() .ConfigureServices((context, services) => { // Use AddInfrastructureInMemory extension for both frameworks services.AddInfrastructureInMemory(); // Register test-specific AutoMapper profiles services.AddAutoMapper(typeof(TestFixture).Assembly); }) .Build(); // Create a scope for scoped services _scope = _host.Services.CreateScope(); #if !NET48 // Ensure database is created (EF Core only) DbContext.Database.EnsureCreated(); #endif } /// /// Create a new service scope (useful for testing scoped lifetime) /// public IServiceScope CreateScope() { return _host.Services.CreateScope(); } /// /// Reset the current scope (creates a new DbContext) /// public void ResetScope() { _scope?.Dispose(); _scope = _host.Services.CreateScope(); } /// /// Clear all data from database /// public async Task ClearDatabaseAsync() { DbContext.ProfileHistories.RemoveRange(DbContext.ProfileHistories); DbContext.ProfileSqlJobs.RemoveRange(DbContext.ProfileSqlJobs); DbContext.CfgProfiles.RemoveRange(DbContext.CfgProfiles); await DbContext.SaveChangesAsync(); } public void Dispose() { _scope?.Dispose(); _host?.Dispose(); } }