Refactor nunit tests off EF InMemory provider and web server

Extract IMicCheckDbContext so DB access can be mocked with Moq instead
of the InMemory provider, per project testing guidelines. Add shared
async DbSet test doubles (TestSupport/) to back the mocks. Rewrite
HTTP-pipeline tests (WebApplicationFactory) to exercise controllers
and auth handlers directly instead of running the web server. Drop
DbContext/seeder tests that only made sense against a real provider,
and remove stale duplicate test files left over from a namespace move.
This commit is contained in:
2026-07-04 19:54:22 -07:00
parent 1556b486d2
commit b4a666ebf0
53 changed files with 1293 additions and 2340 deletions

View File

@@ -1,9 +1,9 @@
using System.Text.Json;
using MicCheck.Api.Audit;
using MicCheck.Api.Data;
using MicCheck.Api.Tests.Unit.TestSupport;
using MicCheck.Api.Webhooks;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Moq;
using NUnit.Framework;
@@ -12,34 +12,31 @@ namespace MicCheck.Api.Tests.Unit.Audit;
[TestFixture]
public class AuditServiceTests
{
private MicCheckDbContext _db = null!;
private Mock<IMicCheckDbContext> _db = null!;
private List<AuditLog> _auditLogs = null!;
private AuditService _service = null!;
private WebhookQueue _queue = null!;
[SetUp]
public void SetUp()
{
var options = new DbContextOptionsBuilder<MicCheckDbContext>()
.UseInMemoryDatabase(Guid.NewGuid().ToString())
.Options;
_db = new MicCheckDbContext(options);
_db = new Mock<IMicCheckDbContext>();
_auditLogs = [];
_db.SetupDbSet(c => c.AuditLogs, _auditLogs);
_queue = new WebhookQueue();
var httpContextAccessor = new Mock<IHttpContextAccessor>();
httpContextAccessor.Setup(x => x.HttpContext).Returns((Microsoft.AspNetCore.Http.HttpContext?)null);
httpContextAccessor.Setup(x => x.HttpContext).Returns((HttpContext?)null);
_service = new AuditService(_db, httpContextAccessor.Object, _queue);
_service = new AuditService(_db.Object, httpContextAccessor.Object, _queue);
}
[TearDown]
public void TearDown() => _db.Dispose();
[Test]
public async Task WhenRecordingWithNoBefore_ThenChangesIsNull()
{
await _service.RecordAsync("Feature", "1", "created", organizationId: 1);
var log = await _db.AuditLogs.FirstAsync();
var log = _auditLogs.First();
Assert.That(log.Changes, Is.Null);
}
@@ -49,7 +46,7 @@ public class AuditServiceTests
var after = new { Name = "dark_mode", Enabled = true };
await _service.RecordAsync("Feature", "1", "created", organizationId: 1, after: after);
var log = await _db.AuditLogs.FirstAsync();
var log = _auditLogs.First();
Assert.That(log.Changes, Is.Not.Null);
var changes = JsonDocument.Parse(log.Changes!).RootElement;
@@ -67,7 +64,7 @@ public class AuditServiceTests
await _service.RecordAsync("FeatureState", "42", "updated", organizationId: 1,
before: before, after: after);
var log = await _db.AuditLogs.FirstAsync();
var log = _auditLogs.First();
var changes = JsonDocument.Parse(log.Changes!).RootElement;
Assert.That(changes.GetProperty("before").GetProperty("enabled").GetBoolean(), Is.False);
@@ -83,7 +80,7 @@ public class AuditServiceTests
"Segment", "5", "deleted",
organizationId: 10, projectId: 20, environmentId: 30);
var log = await _db.AuditLogs.FirstAsync();
var log = _auditLogs.First();
Assert.That(log.ResourceType, Is.EqualTo("Segment"));
Assert.That(log.ResourceId, Is.EqualTo("5"));
Assert.That(log.Action, Is.EqualTo("deleted"));