Moq回调不修改输入参数
本文关键字:输入 参数 修改 回调 Moq | 更新日期: 2023-09-27 18:07:39
问题:
下面的代码不允许我修改传递给Moq模拟的方法的参数。
更多细节:
我试图模拟一个通用的数据访问对象,它提供了一个名为ExecuteStoredProcedureWithParameters
的方法。该方法接受两个参数:存储过程名称和SqlParameter
对象集合。我有通过输出参数返回值的存储过程,因此我试图模拟数据访问方法并修改输出参数的值(这是传入的SqlParameter
集合的成员)。从我的研究,我下面的代码似乎应该工作(我只是试图修改输入参数,将它们设置为空/null用于测试目的)。我在模拟设置中指定的返回值将返回并存储在retval
中,但是在执行模拟方法后,testProcedure
和testParameters
的值保持不变。我做错了什么,我如何修改传递到我的模拟方法的对象?
public interface IGenericDAO
{
int ExecuteStoredProcedureWithParameters(string procedureName, Collection<SqlParameter> parameters);
}
测试方法:// Create a mock generic DAO
var mock = new Mock<IGenericDAO>();
mock.Setup(x => x.ExecuteStoredProcedureWithParameters("TestProcedure", It.IsAny<Collection<SqlParameter>>()))
.Returns(111)
.Callback<string, Collection<SqlParameter>>((proc, prms) => { proc = string.Empty; prms = null; });
// Execute the mocked method with dummy parameters
var testProcedure = "TestProcedure";
var testParameters = new Collection<SqlParameter>();
var retval = mock.Object.ExecuteStoredProcedureWithParameters(testProcedure, testParameters);
将本地变量prms
设置为null。这对实际的testParameters
变量没有影响,因为标准的按值传递语义。Collection
按值传递到函数中,因此像其他变量一样进行浅复制。您所做的类似于这个简单的示例:
void A()
{
int x = 10;
B(x);
Console.WriteLine(x); // 'x' is still 10
}
void B(int x) // input argument copied into local 'x'
{
x = 20; // local 'x' modified
} // local 'x' discarded
这将打印出10,因为只有本地副本x
被修改,然后在函数结束时被丢弃。
在您的实际示例中,如果执行类似prms.Add(new SqlParameter(...))
的操作,那么在调用结束时,testParameters
将包含添加的值。