Unit-тесты сервисов и контроллеров

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

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

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

Что тестировать на уровне 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.

Практика

  1. Покройте сервис заказов: позитивные и негативные сценарии.
  2. Вынесите лямбды Minimal API в статические методы и протестируйте.
  3. Проверьте отмену через CancellationToken.

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

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