Интеграционные тесты: WebApplicationFactory
↑ 3.6 Тестирование ASP.NET Core · ← Предыдущая · → Следующая
Зачем это на собесе
Самый ценный вид тестов для API: весь конвейер в памяти без реального сервера.
Объяснение
WebApplicationFactory<Program> запускает приложение в памяти (TestServer) и даёт HttpClient.
public class ApiFactory : WebApplicationFactory<Program>
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.UseEnvironment("Testing");
builder.ConfigureTestServices(s =>
{
s.RemoveAll<IPaymentGateway>();
s.AddSingleton<IPaymentGateway, FakePaymentGateway>(); // заменяем внешнее
});
}
}
public class OrdersTests(ApiFactory f) : IClassFixture<ApiFactory>
{
[Fact]
public async Task Create_returns_201_and_location()
{
var client = f.CreateClient();
var resp = await client.PostAsJsonAsync("/orders", new { customer = "A", quantity = 1 });
Assert.Equal(HttpStatusCode.Created, resp.StatusCode);
Assert.NotNull(resp.Headers.Location);
}
}Для этого в Program.cs нужен public partial class Program { } (при top-level statements).
Нюансы и подводные камни
- Заменяйте только внешние границы (платежи, почта); внутренности оставляйте настоящими.
- Изолируйте данные между тестами: отдельная схема/БД или очистка (Respawn).
- Аутентификацию подменяют тестовым handler-ом (см. Тестирование авторизации и middleware).
- Фоновые сервисы в тестах отключайте или подменяйте.
- Общий
IClassFixture— общий сервер: не хранить в нём изменяемое состояние.
Практика
- Напишите тесты на CRUD заказов через
WebApplicationFactory. - Подключите Respawn для очистки БД между тестами.
- Подмените внешний HTTP-сервис с помощью WireMock.Net.
Вопросы с ответами
Что даёт WebApplicationFactory?
Полноценный запуск приложения в памяти с реальным конвейером, DI и конфигурацией без сетевого порта.
Как подменить зависимость в тесте?
ConfigureTestServicesилиWithWebHostBuilder.
Как изолировать данные тестов?
Отдельная БД на класс, транзакции с откатом либо Respawn.