Add integration test infrastructure
- Create backend integration test project with xUnit - Add required packages: TestHost, Mvc.Testing, EF InMemory, FluentAssertions - Add project reference to backend API - Create IntegrationTestBase class with WebApplicationFactory setup - Install Supertest for HTTP integration testing
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
using Microsoft.AspNetCore.Mvc.Testing;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using RacePlannerApi.Data;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Net.Http.Json;
|
||||
using System.Text.Json;
|
||||
using Xunit;
|
||||
|
||||
namespace backend.Tests.Integration;
|
||||
|
||||
public class IntegrationTestBase : IClassFixture<WebApplicationFactory<Program>>
|
||||
{
|
||||
protected readonly WebApplicationFactory<Program> _factory;
|
||||
protected readonly HttpClient _client;
|
||||
protected readonly JsonSerializerOptions _jsonOptions = new(JsonSerializerDefaults.Web);
|
||||
|
||||
public IntegrationTestBase(WebApplicationFactory<Program> factory)
|
||||
{
|
||||
_factory = factory.WithWebHostBuilder(builder =>
|
||||
{
|
||||
builder.ConfigureServices(services =>
|
||||
{
|
||||
// Replace the database context with an in-memory database
|
||||
var descriptor = services.SingleOrDefault(
|
||||
d => d.ServiceType == typeof(DbContextOptions<RacePlannerDbContext>));
|
||||
|
||||
if (descriptor != null)
|
||||
{
|
||||
services.Remove(descriptor);
|
||||
}
|
||||
|
||||
services.AddDbContext<RacePlannerDbContext>(options =>
|
||||
{
|
||||
options.UseInMemoryDatabase("IntegrationTestDb");
|
||||
});
|
||||
|
||||
// Ensure the database is created and seeded
|
||||
var sp = services.BuildServiceProvider();
|
||||
using var scope = sp.CreateScope();
|
||||
var db = scope.ServiceProvider.GetRequiredService<RacePlannerDbContext>();
|
||||
db.Database.EnsureCreated();
|
||||
});
|
||||
});
|
||||
|
||||
_client = _factory.CreateClient();
|
||||
}
|
||||
|
||||
protected HttpClient CreateAuthenticatedClient(string token = "")
|
||||
{
|
||||
var client = _factory.CreateClient();
|
||||
if (!string.IsNullOrEmpty(token))
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization =
|
||||
new AuthenticationHeaderValue("Bearer", token);
|
||||
}
|
||||
return client;
|
||||
}
|
||||
|
||||
protected async Task<T?> GetAsync<T>(string url)
|
||||
{
|
||||
var response = await _client.GetAsync(url);
|
||||
response.EnsureSuccessStatusCode();
|
||||
return await response.Content.ReadFromJsonAsync<T>(_jsonOptions);
|
||||
}
|
||||
|
||||
protected async Task<TResponse?> PostAsync<TRequest, TResponse>(string url, TRequest data)
|
||||
{
|
||||
var response = await _client.PostAsJsonAsync(url, data, _jsonOptions);
|
||||
response.EnsureSuccessStatusCode();
|
||||
return await response.Content.ReadFromJsonAsync<TResponse>(_jsonOptions);
|
||||
}
|
||||
|
||||
protected async Task<TResponse?> PutAsync<TRequest, TResponse>(string url, TRequest data)
|
||||
{
|
||||
var response = await _client.PutAsJsonAsync(url, data, _jsonOptions);
|
||||
response.EnsureSuccessStatusCode();
|
||||
return await response.Content.ReadFromJsonAsync<TResponse>(_jsonOptions);
|
||||
}
|
||||
|
||||
protected async Task DeleteAsync(string url)
|
||||
{
|
||||
var response = await _client.DeleteAsync(url);
|
||||
response.EnsureSuccessStatusCode();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user