## Summary - Extract `IMicCheckDbContext` and mock DB access with Moq instead of the EF InMemory provider, per CLAUDE.md testing guidelines. - Rewrite HTTP-pipeline tests to exercise controllers/auth handlers directly instead of `WebApplicationFactory`. - Remove tuple return types across the API in favor of named records (`PagedResult<T>`, `ProfileUpdateResult`, `ApiKeyCreationResult`). ## Test plan - [x] `dotnet build` (full solution) - [x] `dotnet test tests/api/MicCheck.Api.Tests.Unit` — 187/187 pass - [x] `dotnet test tests/api/MicCheck.Api.Tests.Integration` — 8/8 pass (live API + Postgres via Aspire) - [x] Verified Aspire AppHost/dashboard starts and API responds Reviewed-on: #4
30 lines
948 B
C#
30 lines
948 B
C#
using System.Collections;
|
|
using System.Linq.Expressions;
|
|
|
|
namespace MicCheck.Api.Tests.Unit.TestSupport;
|
|
|
|
public class TestAsyncEnumerable<T> : EnumerableQuery<T>, IAsyncEnumerable<T>, IQueryable<T>
|
|
{
|
|
public TestAsyncEnumerable(IEnumerable<T> enumerable) : base(enumerable) { }
|
|
|
|
public TestAsyncEnumerable(Expression expression) : base(expression) { }
|
|
|
|
public IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default) =>
|
|
new TestAsyncEnumerator<T>(this.AsEnumerable().GetEnumerator());
|
|
|
|
IQueryProvider IQueryable.Provider => new TestAsyncQueryProvider<T>(this);
|
|
}
|
|
|
|
public sealed class TestAsyncEnumerator<T>(IEnumerator<T> inner) : IAsyncEnumerator<T>
|
|
{
|
|
public T Current => inner.Current;
|
|
|
|
public ValueTask<bool> MoveNextAsync() => ValueTask.FromResult(inner.MoveNext());
|
|
|
|
public ValueTask DisposeAsync()
|
|
{
|
|
inner.Dispose();
|
|
return ValueTask.CompletedTask;
|
|
}
|
|
}
|