2

在使用 NSubstitute 模拟带有输出参数的方法时,我遇到过这种情况。我不确定如何最好地用文字解释它,所以我将使用一些人为的例子和测试用例......

在这个人为的示例中,我将使用一个 NSubstitute 模拟IDictionary<string, string>.

private static IDictionary<string, string> GetSubstituteDictionary()
{
    IDictionary<string, string> dict = Substitute.For<IDictionary<string, string>>();

    string s;
    dict.TryGetValue("key", out s).Returns(ci => { ci[1] = "value"; return true; });

    return dict;
}

现在,当我以简单的方式使用这个模拟对象时,它会按预期返回:

[Test]
public void ExampleOne()
{
    var dict = GetSubstituteDictionary();

    string value;
    bool result = dict.TryGetValue("key", out value);

    Assert.That(result, Is.True); // this assert passes.
    Assert.That(value, Is.EqualTo("value")); // this assert passes.
}

但是,当我在 for 循环中调用相同的代码时,会出现一些意外行为:

[Test]
public void ExampleTwo()
{
    var dict = GetSubstituteDictionary();

    for (int i = 0; i < 2; i++)
    {
        string value;
        bool result = dict.TryGetValue("key", out value);

        Assert.That(result, Is.True); // this assert FAILS - unexpected!
        Assert.That(value, Is.EqualTo("value")); // this assert still passes.
    }
}

特别是,Assert.That(result, Is.True);断言在循环的第一次迭代中通过,但在第二次(以及任何后续)迭代中失败。

但是,如果我将该string value;行修改为string value = null;,则断言将通过所有迭代。

是什么导致了这种异常?这是由于我缺少 C# for 循环的某些语义,还是 NSubstitute 库的问题?

4

1 回答 1

6

原因是value循环中的变量发生了变化(通过输出参数设置),因此它不再与您存根的调用匹配。

您可以尝试使用.ReturnsForAnyArgs(),尽管您需要检查存根中的密钥,而不是通过参数匹配器。

于 2012-07-26T03:34:47.987 回答