我正在 ASP.NET Core 3.1 中编写 API,使用 EF Core 访问 SQL Server 数据库。我在 API 中有一个函数需要调用一个带有多个输入参数和一个输出参数的存储过程。此功能的简化版本如下。
我正在使用DbContext
with.UseInMemoryDatabase()
进行其他测试,但内存数据库不能与存储过程一起使用。
(这个解决方案是数据库优先,而不是代码优先。如果需要,可以更改存储过程,但如果我不必这样做会好得多。我可以更改我的 C# 函数,以不同的方式调用存储过程虽然如果这有帮助。)
我如何对这个函数进行单元测试?
public class MyFoo : IFoo
{
public ApplicationDbContext DbContext { get; }
public MyFoo(ApplicationDbContext dbContext)
{
DbContext = dbContext;
}
public async Task<bool> GetMyStoredProcResult(string val1, string val2, string val3, string val4, string val5)
{
// input validation removed for brevity
var p1 = new SqlParameter
{
ParameterName = "p1",
DbType = System.Data.DbType.String,
Direction = System.Data.ParameterDirection.Input,
Value = val1
};
// p2 - p5 removed for brevity
var resultParam = new SqlParameter
{
ParameterName = "Result",
DbType = System.Data.DbType.Boolean,
Direction = System.Data.ParameterDirection.Output
};
var sql = "EXEC sp_MyProcedure @p1, @p2, @p3, @p4, @p5, @Result OUTPUT";
_ = await DbContext.Database.ExecuteSqlRawAsync(sql, p1, p2, p3, p4, p5, resultParam);
return (bool)resultParam.Value;
}
}
我的最终解决方案基于 Stas Petrov 给出的答案。我将调用包装为DbContext.Database.ExecuteSqlRawAsync()
使用接口与添加到 DI 中的类Startup.ConfigureServices()
。
我创建了以下接口和类:
public interface IStoredProcedureExecutor
{
public Task<int> ExecuteSqlRawAsync(string sql, params object[] parameters);
}
public class StoredProcedureExecutor : IStoredProcedureExecutor
{
public ApplicationDbContext DbContext { get; }
public StoredProcedureExecutor(ApplicationDbContext dbContext)
{
DbContext = dbContext;
}
public Task<int> ExecuteSqlRawAsync(string sql, params object[] parameters)
{
return DbContext.Database.ExecuteSqlRawAsync(sql, parameters);
}
}
在我的问题代码中,我替换了这个调用:
_ = await DbContext.Database.ExecuteSqlRawAsync(sql, p1, p2, p3, p4, p5, resultParam);
有了这个:
_ = await StoredProcedureExecutor.ExecuteSqlRawAsync(sql, p1, p2, p3, p4, p5, resultParam);
然后在测试代码中,我创建了这个我实例化的类,设置了一个合适的ReturnValue
,然后插入到我正在测试的类中而不是StoredProcedureExecutor
:
class TestStoredProcedureExecutor : IStoredProcedureExecutor
{
public bool ReturnValue { get; set; }
public Task<int> ExecuteSqlRawAsync(string sql, params object[] parameters)
{
foreach (var param in parameters)
{
var p = (SqlParameter)param;
if (p.Direction == System.Data.ParameterDirection.Output) p.Value = ReturnValue;
}
return Task.FromResult(0);
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句