简体   繁体   English

当我不期望它与NSubstitute一起调用函数时

[英]Function is called when I do not expect it to with NSubstitute

I am getting a behaviour I didnt expect from NSubstitute when setting up my mocks to call a function. 在设置我的模拟调用函数时,我得到了一个我从NSubstitute没想到的行为。 A simplified version of the behavuiour is 行为的简化版本是

[Test]
public void NSubstituteTest()
{
    var mockedFoo = Substitute.For<IFoo>();

    mockedFoo.GenerateString(Arg.Any<string>()).Returns(x => GetValue(x.Args()[0]));
    mockedFoo.GenerateString("0").Returns("hi");


    string result1 = mockedFoo.GenerateString("0");
    string result2 = mockedFoo.GenerateString("1");

    Assert.AreEqual("hi", result1);
    Assert.AreEqual("1", result2);
}

private string GetValue(object val)
{
    string returnValue = val != null ? val.ToString() : "I am null";
    System.Diagnostics.Trace.WriteLine(returnValue);
    return returnValue;
}

The test passes but I get the output: 0 1 测试通过,但我得到输出:0 1

This indicates that the call to mockedFoo.GenerateString("0"); 这表明调用了mockedFoo.GenerateString(“0”); actually results in a call to the GetValue() function. 实际上会导致调用GetValue()函数。

If I do the same with Moq: 如果我对Moq做同样的事情:

[Test]
public void MoqTest()
{
    var mockedFoo = new Mock<IFoo>();

    mockedFoo.Setup(x => x.GenerateString(It.IsAny<string>())).Returns((object s) => GetValue(s));
    mockedFoo.Setup(x => x.GenerateString("0")).Returns("hi");


    string result1 = mockedFoo.Object.GenerateString("0");
    string result2 = mockedFoo.Object.GenerateString("1");

    Assert.AreEqual("hi", result1);
    Assert.AreEqual("1", result2);
}

Then my tests also passes but I get the result: 1 然后我的测试也通过但我得到了结果:1

Indicating the function was not called. 表示未调用该功能。

Is this behaviour described somewhere or do I set something up in a wrong way perhaps? 这种行为是在某处描述的,还是我可能以错误的方式设置某些内容?

This is a side-effect of how NSubstitute works: to get that particular syntax it needs to actually call the method to get a reference to that method. 这是NSubstitute如何工作的副作用:要获得实际调用方法以获取对该方法的引用所需的特定语法。

Moq and others use lambdas and can pick the particular method out from there, without the need to run the method itself. Moq和其他人使用lambda,可以从那里选择特定的方法,而无需运行方法本身。 (This means NSubstitute also fails to detect or throw on non-virtual method calls.) (这意味着NSubstitute也无法检测或抛出非虚方法调用。)

The next release will have a work-around for some cases where this is causing problems (albeit a non-ideal one: you'll need to have an argument matcher in the call that sets the return so NSub knows in advance it is not a real call), but the fundamental issue of having to intercept actual method calls will remain. 下一个版本将针对某些导致问题的情况进行解决(虽然这是一个非理想的问题:你需要在调用中设置一个参数匹配器来设置返回值,因此NSub事先知道它不是实际调用),但必须拦截实际方法调用的基本问题仍然存在。

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

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