Введение в WebApplicationFactory. Начало
Сегодня рассмотрим, что такое WebApplicationFactory и как она помогает в тестировании.
Мотивация
Все мы знаем про юнит-тесты, интеграционные тесты и End-to-end тесты. Чёткого разграничения нет. Спросите 10 разработчиков, и они дадут вам 10 разных определений. Но несомненно, что есть код, если модули кода, и их как-то надо тестировать.
В конце концов, пользователю это не важно. Ему важно запросить вашу конечную точку и получить что-то полезное. Поэтому имеет смысл при тестировании смотреть глазами пользователя. Чтобы тестовый клиент был ещё одним пользователем.
Преимущества
1. Если контракт поменяется (как в WebAPI), тест не пройдёт.
2. Вы тестируете всю цепочку и пишете тесты с точки зрения конечного пользователя (не полагаясь на технические детали).
3. Вы получаете хороший обзор ваших функций, таким образом создавая «живую документацию» своего кода.
WebApplicationFactory
Это упрощённый сервер в памяти, который запускает ваш WebAPI ASP.NET Core. Она применит все настройки приложения (включая application.json), DI и будет работать с реальной БД (если не настроено иначе).
Вот простейший минимальный API для примера:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapPost("/", (HelloRequest request) =>
$"Hello {request.Name}!");
app.Run();
И простая запись для запроса:
public record HelloRequest(string Name);
Настроим тестовый проект (xUnit, nUnit, MSTest – какой хотите).
Добавим NuGet-пакет Microsoft.AspNetCore.Mvc.Testing и ссылку с тестового проекта на основной.
Теперь можно написать код настройки тестов. В xUnit используется конструктор:
public class MyApiTests :
IClassFixture<WebApplicationFactory<Program>>
{
public void MyApiTests(
WebApplicationFactory<Program> factory)
{
}
}
Здесь IClassFixture<WebApplicationFactory<Program>> используется, чтобы указать xUnit передать WebApplicationFactory<Program> в конструктор.
Замечания:
1. Называйте классы и методы тестов как модули и их функции, которые вы хотите протестировать. Это важно, если вы хотите иметь живую документацию внутри своего кода.
2. Этот код не скомпилируется. Причина в том, что класс Program является внутренним (internal). В минимальных API больше нет метода Main, компилятор создаёт его за вас. Но теперь там используется модификатор internal. Одним из возможных исправлений было бы добавление InternalsVisibleTo, но это влечёт за собой много исправлений. Тогда тестовые методы также должны быть внутренними. Но внутренние методы не могут быть выполнены тестовой средой. Есть более простой «хак»: с помощью partial класса сделать класс Program публичным. Добавьте в конец файла Program.cs:
public partial class Program
{
}
Не идеально для минимальных API, но просто.
Окончание следует…
Источник: https://steven-giesel.com/blogPost/cd62475b-2c7d-4ce2-bd97-9670f91ebac8/introduction-to-webapplicationfactory