Ответ 1
В настоящее время в EF нет поставщика памяти, но если вы посмотрите на Highway.Data, у него есть базовый интерфейс абстракции и InMemoryDataContext.
Я тестирую код модуляции, написанный против платформы 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 имеет право, где предложение и включить? Я предпочел бы вставить некоторые строки клиентов и некоторые строки заказов, а затем утверждать, что выбран правильный клиент и заказы заполнены.
В настоящее время в EF нет поставщика памяти, но если вы посмотрите на Highway.Data, у него есть базовый интерфейс абстракции и InMemoryDataContext.
Поставщик InMemory включен в EF7 (предварительный выпуск).
Вы можете использовать пакет NuGet или прочитать об этом в EF repo на GitHub (просмотреть источник).
Лучшим подходом здесь может быть использование шаблона репозитория для инкапсуляции вашего EF-кода. При тестировании ваших услуг вы можете использовать макеты или подделки. При тестировании ваших репозиториев вы захотите попасть в реальную БД, чтобы убедиться, что вы получаете ожидаемые результаты.
В статье http://www.codeproject.com/Articles/460175/Two-strategies-for-testing-Entity-Framework-Effort описывается Effort -Entity Framework, который работает в памяти.
Вы все еще можете использовать классы DbContext или ObjectContext в модульных тестах, не имея фактической базы данных.
Да, есть хотя бы один такой провайдер - SQLite. Я использовал его немного, и он работает. Также вы можете попробовать SQL Server Compact. Это встроенная база данных и имеет поставщиков EF.
Edit:
SQLite поддерживает базы данных в памяти (link1). Все, что вам нужно, это указать строку соединения, например: "Источник данных =: память:; Версия = 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, но он имеет некоторые довольно дикие ограничения: