Add RecClientTestBase for integration testing setup

Introduce `RecClientTestBase` to streamline integration tests for `ReCClient`.
This abstract class uses `WebApplicationFactory` to create a test server
for `ReC.API` and configures a `ServiceProvider` with necessary services.
It includes helper methods for creating scoped `ReCClient` instances and
ensures proper resource cleanup via `IDisposable`.

Update `ReC.Tests.csproj` to include:
- `Microsoft.AspNetCore.Mvc.Testing` package for integration testing.
- Project references to `ReC.API` and `ReC.Client` for testing purposes.

These changes establish a reusable and maintainable testing infrastructure.
This commit is contained in:
2026-05-20 11:33:50 +02:00
parent a3aa6ea7ae
commit b724f2e5f4
2 changed files with 78 additions and 0 deletions

View File

@@ -0,0 +1,75 @@
using System;
using System.IO;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using ReC.Client;
namespace ReC.Tests.Client;
public abstract class RecClientTestBase : IDisposable
{
private readonly WebApplicationFactory<Program> _factory;
private readonly ServiceProvider _serviceProvider;
protected RecClientTestBase()
{
var apiContentRoot = LocateApiContentRoot();
_factory = new WebApplicationFactory<Program>()
.WithWebHostBuilder(builder =>
{
builder.UseEnvironment("Development");
builder.UseContentRoot(apiContentRoot);
});
_ = _factory.CreateClient();
var services = new ServiceCollection();
services.AddLogging();
services.AddSingleton(_factory.Services.GetRequiredService<IConfiguration>());
services.AddRecClient(client =>
{
client.BaseAddress = new Uri("http://localhost");
});
services.AddHttpClient(ReCClient.ClientName)
.ConfigurePrimaryHttpMessageHandler(() => _factory.Server.CreateHandler());
_serviceProvider = services.BuildServiceProvider();
}
protected IServiceProvider ServiceProvider => _serviceProvider;
protected IConfiguration Configuration => _factory.Services.GetRequiredService<IConfiguration>();
protected (ReCClient Client, IServiceScope Scope) CreateScopedClient()
{
var scope = _serviceProvider.CreateScope();
var client = scope.ServiceProvider.GetRequiredService<ReCClient>();
return (client, scope);
}
public void Dispose()
{
_serviceProvider.Dispose();
_factory.Dispose();
}
private static string LocateApiContentRoot()
{
var current = new DirectoryInfo(AppContext.BaseDirectory);
while (current is not null)
{
var candidate = Path.Combine(current.FullName, "src", "ReC.API");
if (File.Exists(Path.Combine(candidate, "appsettings.json")))
return candidate;
current = current.Parent;
}
throw new DirectoryNotFoundException("Could not locate src/ReC.API content root from the test base directory.");
}
}

View File

@@ -12,6 +12,7 @@
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0" />
<PackageReference Include="MediatR" Version="14.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.0" />
<PackageReference Include="Moq" Version="4.20.72" />
@@ -21,7 +22,9 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\ReC.API\ReC.API.csproj" />
<ProjectReference Include="..\..\src\ReC.Application\ReC.Application.csproj" />
<ProjectReference Include="..\..\src\ReC.Client\ReC.Client.csproj" />
<ProjectReference Include="..\..\src\ReC.Infrastructure\ReC.Infrastructure.csproj" />
<ProjectReference Include="..\..\src\ReC.Domain\ReC.Domain.csproj" />
</ItemGroup>