Есть ли провайдер в памяти для Entity Framework?
Я являюсь модульным тестовым кодом, написанным для ADO .NET Entity Framework. Я хотел бы заполнить базу данных в памяти строками и убедиться, что мой код извлекает их правильно.
Я могу издеваться над Entity Framework, используя Rhino Mocks, но этого будет недостаточно. Я бы сказал запрос, какие объекты мне вернуть. Это не будет проверять ни предложение where, ни операторы.Include(). Я хочу быть уверен, что мое предложение where соответствует только тем строкам, которые я намереваюсь, и никаким другим. Я хочу быть уверен, что я попросил организации, которые мне нужны, а не те, которые мне не нужны.
Например:
class CustomerService
{
ObjectQuery<Customer> _customerSource;
public CustomerService(ObjectQuery<Customer> customerSource)
{
_customerSource = customerSource;
}
public Customer GetCustomerById(int customerId)
{
var customers = from c in _customerSource.Include("Order")
where c.CustomerID == customerId
select c;
return customers.FirstOrDefault();
}
}
Если я высмеиваю ObjectQuery, чтобы вернуть известного клиента, заполненного заказами, как я узнаю, что CustomerService имеет право where и Включить? Я бы предпочел вставить несколько строк клиента и несколько строк заказа, а затем утверждать, что был выбран правильный клиент и заполнены заказы.
8 ответов
В настоящее время в EF нет провайдера памяти, но если вы посмотрите на Highway.Data, он имеет базовый интерфейс абстракции и InMemoryDataContext.
Поставщик InMemory включен в EF7 (предварительная версия).
Вы можете использовать либо пакет NuGet, либо прочитать об этом в репозитории EF на GitHub ( просмотреть исходный код).
В статье http://www.codeproject.com/Articles/460175/Two-strategies-for-testing-Entity-Framework-Effort описывается Effort - поставщик Entity Framework, работающий в памяти.
Вы все еще можете использовать свои классы DbContext или ObjectContext в модульных тестах, не имея реальной базы данных.
Лучшим подходом здесь может быть использование шаблона Repository для инкапсуляции вашего EF-кода. При тестировании ваших услуг вы можете использовать макеты или подделки. При тестировании ваших репозиториев вы захотите использовать реальную базу данных, чтобы получить ожидаемые результаты.
Да, есть как минимум один такой провайдер - SQLite. Я использовал это немного, и это работает. Также вы можете попробовать SQL Server Compact. Это встроенная база данных, в которой также есть поставщики EF.
Редактировать:
SQLite поддерживает базы данных в памяти ( ссылка 1). Все, что вам нужно, это указать строку подключения, например: "Источник данных =: память:; Версия =3; Новый = Истина;". Если вам нужен пример, вы можете взглянуть на SharpArchitecture.
Я не знаком с Entity Framework и классом ObjectQuery, но если метод Include является виртуальным, вы можете смоделировать его следующим образом:
// Arrange
var customerSourceStub = MockRepository.GenerateStub<ObjectQuery<Customer>>();
var customers = new Customer[]
{
// Populate your customers as if they were coming from DB
};
customerSourceStub
.Stub(x => x.Include("Order"))
.Return(customers);
var sut = new CustomerService(customerSourceStub);
// Act
var actual = sut.GetCustomerById(5);
// Assert
Assert.IsNotNull(actual);
Assert.AreEqual(5, actual.Id);
Вы можете попробовать SQL Server Compact, но у него есть довольно дикие ограничения:
- SQL Server Compact не поддерживает выражения SKIP в запросах подкачки, когда он используется с Entity Framework
- SQL Server Compact не поддерживает объекты с сгенерированными сервером ключами или значениями при использовании с Entity Framework
- Нет внешних соединений, сортировка, по модулю поплавки, агрегаты
В EF Core есть два основных способа сделать это:
- Режим SQLite в оперативной памяти позволяет вам создавать эффективные тесты для провайдера, который ведет себя как реляционная база данных.
- Поставщик InMemory - это облегченный поставщик, который имеет минимальные зависимости, но не всегда ведет себя как реляционная база данных.
Я использую SQLite, и он поддерживает все запросы, которые мне нужно сделать с производственной базой данных SQL Azure.