如何使用 Moq 模拟 SqlParameterCollection
我正在尝试模拟数据库操作。我在模拟 SqlParameterCollection
时遇到问题。我尝试创建将返回 DbParameterCollection 的 virtual
方法,但随后我失去了 SqlParameterCollection
提供的所有功能,例如 AddWithValue
> 等等。有没有办法可以模拟 SqlParameterCollection
?还有其他方法来单元测试 DAL 吗?我正在使用起订量。
代码如下:
在 DAL 中:
protected virtual IDbConnection GetConnection(string connectionString)
{
return new SqlConnection(connectionString);
}
protected virtual IDbCommand GetCommand(IDbConnection cn)
{
return cn.CreateCommand();
}
protected virtual IDbTransaction GetTransaction(IDbConnection cn)
{
return cn.BeginTransaction(IsolationLevel.Serializable);
}
Public Bool InsertInDatabase(DataTable dt)
{
using (IDbConnection cn = GetConnection(cnstr))
{
cn.Open();
using (IDbTransaction tran = GetTransaction(cn))
{
IDbCommand cmd = GetCommand(cn);
cmd.Transaction = tran;
cmd.Connection = cn;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "sp_InsertInDatabase";
SqlParameterCollection cmdParams = cmd.Parameters as SqlParameterCollection;
cmdParams.AddWithValue("@param1", dt);
cmd.ExecuteNonQuery();
}
}
}
在单元测试项目中:
protected override IDbConnection GetConnection(string connectionString)
{
return Mock.Of<IDbConnection>();
}
protected override IDbCommand GetCommand(IDbConnection cn)
{
return Mock.Of<IDbCommand>();
}
protected override IDbTransaction GetTransaction(IDbConnection cn)
{
return Mock.Of<IDbTransaction>();
}
public void TestInsertInDatabase()
{
base.InsertInDatabase(new DataTable());
}
--解决方案--
创建了一个扩展方法来添加带有值的参数。谢谢马克·格拉维尔为我指明了这个方向。
public static IDbDataParameter AddParameterWithValue(this IDbCommand cmd, string paramName, object paramValue)
{
var dbParam = cmd.CreateParameter();
if (dbParam != null)
{
dbParam.ParameterName = paramName;
dbParam.Value = paramValue;
}
return dbParam;
}
I am trying to mock database operations. I have problem in mocking SqlParameterCollection
. I tried to create virtual
method that will return DbParameterCollection
but then i am loosing all the functionality that SqlParameterCollection
gives like AddWithValue
etc. Is there a way i can mock SqlParameterCollection
? Is there any other approach to unit test DAL? I am using Moq.
Code goes like this:
in DAL:
protected virtual IDbConnection GetConnection(string connectionString)
{
return new SqlConnection(connectionString);
}
protected virtual IDbCommand GetCommand(IDbConnection cn)
{
return cn.CreateCommand();
}
protected virtual IDbTransaction GetTransaction(IDbConnection cn)
{
return cn.BeginTransaction(IsolationLevel.Serializable);
}
Public Bool InsertInDatabase(DataTable dt)
{
using (IDbConnection cn = GetConnection(cnstr))
{
cn.Open();
using (IDbTransaction tran = GetTransaction(cn))
{
IDbCommand cmd = GetCommand(cn);
cmd.Transaction = tran;
cmd.Connection = cn;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "sp_InsertInDatabase";
SqlParameterCollection cmdParams = cmd.Parameters as SqlParameterCollection;
cmdParams.AddWithValue("@param1", dt);
cmd.ExecuteNonQuery();
}
}
}
In Unit test project:
protected override IDbConnection GetConnection(string connectionString)
{
return Mock.Of<IDbConnection>();
}
protected override IDbCommand GetCommand(IDbConnection cn)
{
return Mock.Of<IDbCommand>();
}
protected override IDbTransaction GetTransaction(IDbConnection cn)
{
return Mock.Of<IDbTransaction>();
}
public void TestInsertInDatabase()
{
base.InsertInDatabase(new DataTable());
}
--Solution--
Created an extension method to add parameter with value. Thank you Marc Gravell for pointing me to that direction.
public static IDbDataParameter AddParameterWithValue(this IDbCommand cmd, string paramName, object paramValue)
{
var dbParam = cmd.CreateParameter();
if (dbParam != null)
{
dbParam.ParameterName = paramName;
dbParam.Value = paramValue;
}
return dbParam;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
就我个人而言,我通过向
DbCommand
(或IDbCommand
)编写一个AddParameterWithValue
扩展方法来解决此问题。它必须位于命令上,以便您可以访问CreateParameter
,然后调用.Parameters.Add
。这允许轻松地使用任何 ADO.NET 堆栈,包括日志装饰器等抽象。
Personally, I approach this problem by writing an
AddParameterWithValue
extension method toDbCommand
(orIDbCommand
). It has to be on the command so that you have access toCreateParameter
, and then call.Parameters.Add
.This allows easy usage against any ADO.NET stack, including abstractions like logging decorators.
@Asdfg HI 我基本上已经模拟了参数集合,如下
希望这会有所帮助
@Asdfg HI I have basically mocked the parameter collection as below
Hope this helps
嗨,我找到了解决方案。
我必须为 IDataParameterCollection 接口实现 Moq,并且必须将其发送到 IDbCommand 的实例。
这样我的 IDbCommand.Parameters 对象就不再是 null 了。
Hi i found the solution.
I had to implement a Moq for the IDataParameterCollection interface and had to send it to the instance of IDbCommand.
With that my IDbCommand.Parameters object became different from null.
如果您不想添加扩展方法只是为了使您的代码可测试(如该问题的另一个答案中所建议的),您可以轻松地模拟您的方法,如下所示:
If you don't want to add extension method just to make your code testable (as proposed in another answer to this question) you can easily mock your way around this like so: