我遇到的情况是使用NSubstitute使用输出参数模拟方法时的情况。 我不确定如何最好地在文本中解释它,所以我将使用一些人为的例子和测试用例......
在这个人为的例子中,我将使用一个IDictionary<string, string>
的NSubstitute模拟。
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库的问题?
答案 0 :(得分:4)
原因是value
变量在循环中发生变化(通过输出参数设置),因此它不再匹配您存根的调用。
您可以尝试使用.ReturnsForAnyArgs()
,但您需要检查存根中的密钥,而不是通过参数匹配器。