InMemory и SQLite провайдеры: подводные камни
↑ 4.3 Тестирование слоя данных · → Следующая
Зачем это на собесе
«Как вы тестируете код с EF?» — ловушка: InMemory выглядит удобно, но обманывает.
Объяснение
| Провайдер | Скорость | Транзакции | Ограничения и SQL | Вывод |
|---|---|---|---|---|
UseInMemoryDatabase | максимальная | нет | не проверяет FK, unique, типы; не SQL | подходит только для простых демо |
| SQLite in-memory | высокая | да | диалект ≠ PostgreSQL, нет многих типов/функций | компромисс |
| Реальная БД (Testcontainers) | ниже | да | полное соответствие | рекомендуется для интеграционных тестов |
// InMemory пропустит то, что в реальной БД упадёт
db.Orders.Add(new Order { CustomerId = Guid.NewGuid() }); // FK на несуществующего клиента
await db.SaveChangesAsync(); // ok в InMemory, ошибка в PostgreSQLПрактическое правило: логику unit-тестируйте без БД (fake-репозитории), запросы и схему — на настоящей СУБД.
Нюансы и подводные камни
- InMemory не поддерживает
ExecuteUpdate, сырой SQL, транзакции,xmin, JSON-колонки. - В SQLite отличаются
DateTimeOffset,decimal, регистр строк, сортировка. - Тесты «зелёные» на InMemory могут скрывать баги трансляции LINQ.
- Команда EF Core прямо не рекомендует InMemory для тестирования.
Практика
- Найдите тесты на InMemory и проверьте на реальной БД, какие ошибки они скрывали.
- Напишите тест, нарушающий FK/unique, и посмотрите различие.
- Переведите тестовую фикстуру на Testcontainers.
Вопросы с ответами
Почему не стоит использовать EF InMemory?
Он не реализует поведение реальной БД (ограничения, транзакции, SQL), поэтому тесты дают ложную уверенность.
Когда допустим SQLite?
Если продакшен использует SQLite или запросы простые; иначе диалектные отличия скрывают ошибки.