Unit-тесты сервисов и контроллеров
↑ 3.6 Тестирование ASP.NET Core · → Следующая
Зачем это на собесе
Что тестировать на уровне unit, а что оставить интеграционным тестам.
Объяснение
Тонкие контроллеры/endpoint-ы почти не содержат логики, поэтому unit-тестируют сервисы и handlers, а HTTP-слой — интеграционными тестами.
public class OrderServiceTests
{
private readonly InMemoryOrders _repo = new();
private readonly FakeTimeProvider _time = new();
[Fact]
public async Task Cancel_paid_order_throws()
{
var order = await _repo.AddAsync(Order.Paid());
var sut = new OrderService(_repo, _time);
await Assert.ThrowsAsync<ConflictException>(() => sut.CancelAsync(order.Id, default));
}
}Контроллер тоже можно вызвать напрямую, если он возвращает ActionResult<T>:
var result = await controller.Get(id, default);
var ok = Assert.IsType<OkObjectResult>(result.Result);Но Minimal API-лямбды так не проверить — выносите обработчики в методы.
Нюансы и подводные камни
- Unit-тесты не проверяют маршрутизацию, привязку, фильтры, сериализацию — для этого интеграционные тесты.
- Мок
DbContextне показывает ошибок SQL — используйте реальную БД. - Тестируйте поведение (что вернулось, что сохранилось), а не вызовы.
- Одна ответственность на тест, читаемые имена:
Method_State_Expected.
Практика
- Покройте сервис заказов: позитивные и негативные сценарии.
- Вынесите лямбды Minimal API в статические методы и протестируйте.
- Проверьте отмену через
CancellationToken.
Вопросы с ответами
Что тестировать unit-ами в web API?
Бизнес-логику сервисов и handlers, мапперы, валидаторы; HTTP-слой — интеграционными.
Стоит ли мокать DbContext?
Нет: используйте настоящую БД (Testcontainers) или fake-репозиторий на границе.