Интеграционные тесты: WebApplicationFactory

↑ 3.6 Тестирование ASP.NET Core · ← Предыдущая · → Следующая

Обязательно~3 мин чтенияУровень: middle

Зачем это на собесе

Самый ценный вид тестов для 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 — общий сервер: не хранить в нём изменяемое состояние.

Практика

  1. Напишите тесты на CRUD заказов через WebApplicationFactory.
  2. Подключите Respawn для очистки БД между тестами.
  3. Подмените внешний HTTP-сервис с помощью WireMock.Net.

Вопросы с ответами

Связанные темы