使用Moq,你如何模拟使用局部变量的方法

时间:2016-10-20 22:11:25

标签: c# unit-testing moq

Moq的新手,这是一个非常简单的例子。我想模拟对我的“int smokeTest(int a,int b)”方法的调用,该方法在我的方法“string getCode(int someID)”中使用。 smokeTest的变量在getCode中声明和设置。问题是当我模拟对smokeTest的方法调用时,我总是在getCode中得到“0”的结果,但我想看到我的预定义结果“20”。我发现的唯一工作是重载方法并传入所有变量。但是,我不想这样做,因为我想要测试的许多方法都声明并使用局部变量。使用Moq测试此方法的最佳方法是什么?感谢

// Example A
public string getCode(int someID)
{
    int x = 5;
    int y = 5;
    int z = _dataAccess.smokeTest(x, y);

    return _dataAccess.getCode(someID);
}

// NOTE: Doesn't work as wanted
[Test]
public void test_getCode_TestB()
{
    var x = It.IsAny<int>();
    var y = It.IsAny<int>();

    // NOTE: "20" is not returned, 0 is returned instead because local variables are used
    _mockDataAccess.Setup(m => m.smokeTest(x, y)).Returns(20);
    _mockDataAccess.Setup(m => m.getCode(234)).Returns("def345");

    var result = _businessLogic.getCode(234);

    Assert.IsTrue(result == "def345");
}

// Example B

// NOTE: Workaround - pass in variables
public string getCode(int someID, int a, int b)
{
    var c = _dataAccess.smokeTest(a, b);
    return _dataAccess.getCode(someID);
}       

[Test]
public void test_getCode_TestC()
{
    var x = It.IsAny<int>();
    var y = It.IsAny<int>();

    // NOTE: "20" is returned as wanted
    _mockDataAccess.Setup(m => m.smokeTest(x, y)).Returns(20);
    _mockDataAccess.Setup(m => m.getCode(234)).Returns("def345");

    var result = _businessLogic.getCode(234, x, y);
    Assert.IsTrue(result == "def345");
}

1 个答案:

答案 0 :(得分:4)

仅当您将It.IsAny<int>()直接传递到moq设置时才会有效:

_mockDataAccess.Setup(m => m.smokeTest(It.IsAny<int>(), It.IsAny<int>())).Returns(20);

我正在浏览moq源代码,发现这样做:

int x = It.IsAny<int>();
int y = It.IsAny<int>();
_mockDataAccess.Setup(m => m.smokeTest(x, y)).Returns(20);

将x和y设为int的deafult值,即0,所以你的设置等同于:

_mockDataAccess.Setup(m => m.smokeTest(0, 0)).Returns(20); 

如果参数为0和0,则此设置告诉moq返回20,否则它将返回int的deafult值,再次为0。这不是您打算创建的行为,因此在将它们传递到moq设置之前,不应将It.IsAny<int>()分配到x和y中。

由于@Rob注释表明It.IsAny<T>是一种可以传递给moq设置的存根,因此setup方法将知道如何使用Expression Trees处理它,但此方法实际返回的值是始终是T的狡猾。这就是为什么我们必须总是直接在moq设置中使用这种方法。