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.
44 lines
1.8 KiB
C#
44 lines
1.8 KiB
C#
using System.Linq.Expressions;
|
|
using Microsoft.EntityFrameworkCore.Query;
|
|
|
|
namespace MicCheck.Api.Tests.Unit.TestSupport;
|
|
|
|
public class TestAsyncQueryProvider<T>(IQueryProvider innerProvider) : IAsyncQueryProvider
|
|
{
|
|
public IQueryable CreateQuery(Expression expression) =>
|
|
new TestAsyncEnumerable<T>(StripIncludes(expression));
|
|
|
|
public IQueryable<TElement> CreateQuery<TElement>(Expression expression) =>
|
|
new TestAsyncEnumerable<TElement>(StripIncludes(expression));
|
|
|
|
public object? Execute(Expression expression) =>
|
|
innerProvider.Execute(StripIncludes(expression));
|
|
|
|
public TResult Execute<TResult>(Expression expression) =>
|
|
innerProvider.Execute<TResult>(StripIncludes(expression));
|
|
|
|
public TResult ExecuteAsync<TResult>(Expression expression, CancellationToken cancellationToken = default)
|
|
{
|
|
var stripped = StripIncludes(expression);
|
|
var resultType = typeof(TResult).GetGenericArguments() is [var inner] ? inner : typeof(TResult);
|
|
var executionResult = typeof(IQueryProvider)
|
|
.GetMethod(nameof(IQueryProvider.Execute), 1, [typeof(Expression)])!
|
|
.MakeGenericMethod(resultType)
|
|
.Invoke(innerProvider, [stripped]);
|
|
|
|
return (TResult)typeof(Task).GetMethod(nameof(Task.FromResult))!
|
|
.MakeGenericMethod(resultType)
|
|
.Invoke(null, [executionResult])!;
|
|
}
|
|
|
|
private static Expression StripIncludes(Expression expression) => new IncludeStripVisitor().Visit(expression);
|
|
|
|
private sealed class IncludeStripVisitor : ExpressionVisitor
|
|
{
|
|
protected override Expression VisitMethodCall(MethodCallExpression node) =>
|
|
node.Method.Name is "Include" or "ThenInclude"
|
|
? Visit(node.Arguments[0])
|
|
: base.VisitMethodCall(node);
|
|
}
|
|
}
|