¿Hay un proveedor en memoria para Entity Framework?
entity-framework rhino-mocks (8)
Soy un código de prueba unitaria escrito contra ADO .NET Entity Framework. Me gustaría rellenar una base de datos en memoria con filas y asegurarme de que mi código las recupere correctamente.
Puedo simular el Entity Framework usando Rhino Mocks, pero eso no sería suficiente. Diría la consulta qué entidades me devolverán. Esto tampoco probaría la cláusula where ni las sentencias .Include (). Quiero estar seguro de que mi cláusula where coincide solo con las filas que intento, y no con otras. Quiero estar seguro de haber pedido las entidades que necesito, y ninguna que no tenga.
Por ejemplo:
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();
}
}
Si me burlo de ObjectQuery para devolver un cliente conocido con pedidos, ¿cómo sé que CustomerService tiene la cláusula right where y Include? Preferiría insertar algunas filas de clientes y algunas filas de pedidos, y luego afirmar que se seleccionó al cliente correcto y que los pedidos se completaron.
No estoy familiarizado con Entity Framework y la clase ObjectQuery, pero si el método Include es virtual, puedes simularlo así:
// 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);
Un mejor enfoque aquí podría ser utilizar el patrón Repositorio para encapsular su código EF. Al probar sus servicios, puede usar simulaciones o falsificaciones. Al probar sus repositorios, querrá acceder a la base de datos real para asegurarse de obtener los resultados que espera.
Puede probar SQL Server Compact, pero tiene algunas limitaciones bastante salvajes:
- SQL Server Compact no admite expresiones SKIP en consultas de paginación cuando se utiliza con Entity Framework
- SQL Server Compact no admite entidades con claves o valores generados por el servidor cuando se utiliza con Entity Framework
- Sin uniones externas, cotejo, módulo sobre flotadores, agregados
Sí, hay al menos uno de esos proveedores: SQLite . Lo he usado un poco y funciona. También puedes probar SQL Server Compact . Es una base de datos incrustada y también tiene proveedores de EF.
Editar:
SQLite tiene soporte para bases de datos en memoria ( link1 ). Todo lo que necesita es especificar una cadena de conexión como: "Data Source =: memory:; Version = 3; New = True;". Si necesita un ejemplo, puede mirar SharpArchitecture .
Actualmente no existe un proveedor de memoria para EF, pero si echa un vistazo a Highway.Data tiene una interfaz de abstracción básica y un InMemoryDataContext.
Un proveedor de InMemory está incluido en EF7 (prelanzamiento).
Puede usar el paquete NuGet o leer sobre él en el repositorio EF en GitHub ( ver fuente ).
El artículo http://www.codeproject.com/Articles/460175/Two-strategies-for-testing-Entity-Framework-Effort describe el proveedor Effort -Entity Framework que se ejecuta en la memoria.
Aún puede usar sus clases de DbContext o ObjectContext en pruebas unitarias, sin tener que tener una base de datos real.
En EF Core hay dos opciones principales para hacer esto:
- El modo en memoria de SQLite le permite escribir pruebas eficientes contra un proveedor que se comporta como una base de datos relacional.
- El proveedor InMemory es un proveedor liviano que tiene dependencias mínimas, pero no siempre se comporta como una base de datos relacional
Estoy usando SQLite y admite todas las consultas, que tengo que hacer con la base de datos de producción de Azure SQL.