У меня есть функция, вызывающая хранимую процедуру с 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();
}
И я хотел бы создать для него единичный тест с использованием Effort. У меня уже есть Effort (и база данных NMemory) для имитации базы данных (основанной на моем контексте), на Initialize
для каждого модульного теста, например:
[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();
}
}
Где EffortProviderFactory
:
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;
}
}
}
Я протестировал добавление создания хранимой процедуры следующим образом:
[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");
}
}
Но он генерирует NotSupportedException
. Как я могу это сделать, и каков наилучший способ?
Усилия - это основанный на файлах поставщик базы данных в базе данных, который снабжает экземпляр DbContext
частной временной базой данных: новым контекстом, новой базой данных и без тестовых взаимодействий. Это хорошая часть.
Недостатком, конечно же, является то, что он не является и никогда не будет ... полноценным движком базы данных. Поэтому он никогда не будет поддерживать хранимые процедуры, написанные на любом из распространенных диалектов SQL (например, t-SQL или PL-SQL). Поскольку Усилия (т.е. NMemory) хранит процедуры, это всего лишь сохраненный IQueryable
, как видно из конструктора StoredProcedure
. Отмечается удаленно связанный с хранимыми процедурами t-SQL.
Единственный способ проверить хранимые процедуры в коде уровня доступа к данным - это очень хорошая идея - написать интеграционные тесты. Существует примерно два подхода к тому, чтобы интеграционные тесты были независимыми друг от друга:
Создание / семена новой базы данных для каждого теста
Используйте существующую базу данных с тестовыми примерами и откатывайте изменения после каждого теста, например, используя TransactionScope .
Тесты интеграции никогда не будут такими быстрыми, как модульные тесты, и они дополняют только единичные тесты, но, тем не менее, в моей собственной практике кодирования, связанной с уровнями данных, они стали первоклассными гражданами в наборе тестов. Для меня правильность важнее скорости.