Какой тип теста тестирует метод с доступом к базе данных
Что проверяют
Различаете ли вы юнит- и интеграционные тесты не по названию папки, а по тому, что реально исполняется. Короткий правильный ответ: если метод действительно ходит в базу, это интеграционный тест. Следом почти всегда спрашивают, чем плох EF Core InMemory и как вы изолируете тесты друг от друга.
Как отвечать
Разведите два случая:
- юнит-тест: базу прячут за абстракцию вроде
IOrderRepositoryи подменяют моком через Moq или NSubstitute. Проверяется логика вокруг данных, а не сам запрос. Быстро, но SQL, маппинг и ограничения схемы не проверяются вообще; - интеграционный тест: метод работает с настоящей СУБД. Проверяется трансляция LINQ в SQL, миграции, уникальные индексы, каскадное удаление, транзакции.
Для интеграционных тестов в .NET сейчас стандарт такой: Testcontainers поднимает в Docker ту же СУБД, что на проде (PostgreSqlBuilder, MsSqlBuilder), контейнер стартует в фикстуре xUnit через IAsyncLifetime и живёт на весь класс или коллекцию тестов. Для API сверху добавляется WebApplicationFactory<Program>, где подменяется строка подключения. Между тестами состояние чистят откатом транзакции или библиотекой Respawn, которая очищает таблицы быстрее, чем пересоздание базы.
Про провайдер UseInMemoryDatabase скажите прямо: сама Microsoft не советует тестировать им код доступа к данным. Он не реляционный, не проверяет внешние ключи, не выполняет сырой SQL. SQLite в памяти ближе к правде, но диалект всё равно другой.
Где спотыкаются
Называют юнит-тестом проверку с моком DbContext и DbSet. Такой тест гоняет LINQ to Objects в памяти, и запрос, который упадёт на трансляции в SQL, у него пройдёт.
Считают InMemory «лёгкой базой для тестов». Зелёные тесты при этом ничего не гарантируют: регистр строк, ограничения и транзакции там ведут себя не так, как в настоящей СУБД.
Не думают об изоляции. Тесты пишут в общую базу, зависят от порядка запуска и начинают падать при параллельном прогоне.