问题:
下面的代码不允许我修改我传递给Moq模拟的方法的参数。
其他详细信息:
我正在尝试模拟一个提供名为ExecuteStoredProcedureWithParameters
的方法的通用数据访问对象。该方法接受两个参数:存储过程名称和SqlParameter
个对象的集合。我有通过输出参数返回值的存储过程,所以我试图模拟数据访问方法并修改输出参数的值(它是传入的SqlParameter
集合的成员)。根据我的研究,我下面的代码似乎应该可以工作(我只是试图通过将它们设置为空/ null来修改输入参数以进行测试)。我在模拟设置中指定的返回值被返回并存储在retval
中,但是testProcedure
和testParameters
的值在执行模拟方法后保持不变。我做错了什么,如何修改传递给我的mock方法的对象?
我的界面:
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);
答案 0 :(得分:2)
您正在将局部变量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
将包含附加值。