在Effort数据库上创建单元测试的存储过程

时间:2017-10-31 10:46:37

标签: c# entity-framework unit-testing stored-procedures effort

我有一个使用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。我该怎么做,最好的方法是什么?

1 个答案:

答案 0 :(得分:4)

Effort是一个基于文件的内存数据库提供程序,为DbContext实例提供私有的临时数据库:新上下文,新数据库,无测试交互。那是好事。

当然,缺点是它不是 - 而且永远不会 - 是一个成熟的数据库引擎。因此,永远不会支持用任何常见SQL方言(如t-SQL或PL-SQL)编写的存储过程。至于Effort(即NMemory)存储过程,它只是一个存储的IQueryable,从StoredProcedure constructor可以看出。注意与t-SQL存储过程远程相关。

在数据访问层代码中测试存储过程的唯一方法是编写集成测试,这是一个非常好的想法。大致有两种方法可以使集成测试彼此独立:

集成测试永远不会像单元测试一样快,它们只是补充单元测试,但是,在我自己的与数据层相关的编码实践中,它们已成为单元测试中的一等公民测试套件。对我而言,正确性比速度更重要。