简体   繁体   English

Moq回调不修改输入参数

[英]Moq callback not modifying input parameters

The problem: 问题:

The code below does not allow me to modify the parameters that I pass into a method that has been mocked with Moq. 下面的代码不允许我修改传入Moq模拟的方法中的参数。

Additional details: 额外细节:

I am attempting to mock a generic data access object that provides a method called ExecuteStoredProcedureWithParameters . 我正在尝试模拟通用数据访问对象,该对象提供了一种称为ExecuteStoredProcedureWithParameters的方法。 The method accepts two parameters: a stored procedure name and a collection of SqlParameter objects. 该方法接受两个参数:存储过程名称和SqlParameter对象的集合。 I have stored procedures that return values via output parameters, so I am attempting to mock the data access method and modify the value of the output parameter (which is a member of the SqlParameter collection that gets passed in). 我已经存储了通过输出参数返回值的过程,因此我试图模拟数据访问方法并修改输出参数的值(该参数是传入的SqlParameter集合的成员)。 From my research, the code I have below seems like it should work (I'm just attempting to modify the input parameters by setting them to empty/null for testing purposes). 根据我的研究,下面的代码似乎应该可以工作(我只是为了通过测试将输入参数设置为空/空来尝试修改输入参数)。 The return value I specified in my mock setup gets returned and stored in retval , however the values of testProcedure and testParameters remain unchanged after the mock method is executed. 我在模拟设置中指定的返回值将返回并存储在retval ,但是在执行模拟方法后, testProceduretestParameters的值保持不变。 What am I doing wrong and how can I modify the objects that are passed into my mock method? 我在做什么错,我该如何修改传递给我的模拟方法的对象?

My interface: 我的界面:

public interface IGenericDAO
{
    int ExecuteStoredProcedureWithParameters(string procedureName, Collection<SqlParameter> parameters);
}

Test method: 测试方法:

// 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);

You are setting the local variable prms to null. 您正在将局部变量prms设置为null。 This has no effect on the actual testParameters variable because of standard pass-by-value semantics. 由于标准的按值传递语义,这对实际的testParameters变量没有影响。 The Collection is passed by value into the function and so is shallow-copied like any other variable. Collection通过值传递到函数中,因此像任何其他变量一样浅复制。 What you are doing is similar to this trivial example: 您正在执行的操作与此简单的示例相似:

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

This will print out 10, because only the local copy x is modified and then thrown away at the end of the function. 这将打印出10,因为只有本地副本x被修改,然后在函数末尾被丢弃。

In your actual example, if do something like prms.Add(new SqlParameter(...)) then, at the end of the call, testParameters will contain the added value. 在您的实际示例中,如果执行类似prms.Add(new SqlParameter(...))则在调用结束时, testParameters将包含添加的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM