Tengo una función que llama a un procedimiento almacenado con Entity Framework:
public async Task<List<Entity>> GetEntity(int id)
{
var param = new SqlParameter("@id", id);
return await myContext.Database
.SqlQuery<MyEntity>("[myStoredProcedure] @id", param)
.ToListAsync();
}
Y me gustaría crear una prueba unitaria para ella usando Effort. Ya tengo Effort (y la base de datos NMemory) para simular una base de datos (en función de mi contexto), en Initialize
para cada prueba de unidad, como:
[TestInitialize]
public void Initialize()
{
Effort.Provider.EffortProviderConfiguration.RegisterProvider();
EffortProviderFactory.ResetDb()
using (var context = new MyContext("PWET"))
{
context.Database.CreateIfNotExists();
context.Constructeurs.Add(new Constructeur { Nom = "Zebra" });
context.Constructeurs.Add(new Constructeur { Nom = "Joya" });
context.SaveChanges();
}
}
Donde EffortProviderFactory
es:
public class EffortProviderFactory : IDbConnectionFactory
{
private static DbConnection _connection;
private readonly static object _lock = new object();
public static void ResetDb(){
lock (_lock){
_connection = null;
}
}
public DbConnection CreateConnection(string nameOrConnectionString)
{
lock (_lock){
if (_connection == null)
_connection = Effort.DbConnectionFactory.CreateTransient();
return _connection;
}
}
}
Probé agregando la creación del procedimiento almacenado de esa manera:
[TestInitialize]
public void Initialize()
{
Effort.Provider.EffortProviderConfiguration.RegisterProvider();
EffortProviderFactory.ResetDb()
using (var context = new MyContext("PWET"))
{
context.Database.CreateIfNotExists();
context.Database.ExecuteSqlCommand(@"
CREATE PROCEDURE [dbo].[myStoredProcedure]
@id INT = 0
AS
BEGIN
SELECT foo
FROM bar
WHERE foo.Id = @id
ORDER BY foo.Id;
END");
}
}
Pero lanza una NotSupportedException
. ¿Cómo puedo hacer, y cuál es la mejor manera?
Effort es un proveedor de base de datos en memoria basado en archivos que suministra una instancia de DbContext
con una base de datos temporal privada: nuevo contexto, nueva base de datos, sin interacciones de prueba. Esa es la parte buena.
La desventaja, por supuesto, es que no es, y nunca lo será, un motor de base de datos completo. Por lo tanto, nunca admitirá procedimientos almacenados escritos en ninguno de los dialectos de SQL comunes (como t-SQL o PL-SQL). En cuanto a Effort (es decir, NMemory) tiene procedimientos almacenados, es simplemente un IQueryable
almacenado, como se desprende del constructor StoredProcedure
. Observación remota relacionada con los procedimientos almacenados de t-SQL.
La única forma de probar los procedimientos almacenados en el código de la capa de acceso a datos, que es una muy buena idea, es escribir pruebas de integración. Existen aproximadamente dos enfoques para hacer que las pruebas de integración sean independientes entre sí:
Crear / sembrar una nueva base de datos para cada prueba
Utilice una base de datos existente con casos de prueba y deshaga los cambios después de cada prueba, por ejemplo, utilizando TransactionScope .
Las pruebas de integración nunca serán tan rápidas como las pruebas unitarias y solo complementan las pruebas unitarias, sin embargo, en mi propia práctica de codificación relacionada con las capas de datos, se han convertido en ciudadanos de primera clase en la suite de pruebas. Para mí, la corrección es más importante que la velocidad.