NSubstitute ForPartsOf 被替换时调用具体实现事件

NSubstitute ForPartsOf calling concrete implementation event when substituted

我有以下 class:

public class MyClass : IMyClass
{
    public string MyFunc(string name)
    {            
        if (string.IsNullOrWhiteSpace(name))
        {
            throw new Exception("Blank Name");
        }

        return name;
    }

    public double MyFuncWrapper(string name)
    {
        var value = MyFunc(name);

        return value;
    }

在尝试对其进行测试时,我的印象是 NSubstitute 的 ForPartsOf 有效地替代了 class 我的 class 并替换了标记的方法;所以我这样做了:

[Fact]
public void TestMyFuncWrapper()
{
    // Arrange
    var myClass = Substitute.ForPartsOf<MyClass>();            
    myClass.MyFunc(Arg.Any<string>()).Returns("Test");

    // Act
    var result = myClass.MyFuncWrapper("");

    // Assert
    Assert.Equal("Test", result);
}

但是,据我所知,我的替代方法引发了异常。奇怪的是,下面一行似乎是:

myClass.MyFunc(Arg.Any<string>()).Returns("Test");

实际上是立即调用具体函数。查看 here,似乎这样的构造可能会解决问题(尽管它确实使用了听起来很模糊的短语 "playing it safe"):

myClass.When(a => a.MyFunc(Arg.Any<string>())).DoNotCallBase();

但是,调用它实际上会以相同的方式立即调用 MyFunc。显然我误解了 ForPartsOf 方法;我的问题是:我可以使用 NSubstitute 做我正在尝试的事情,还是我需要诉诸手动 subclassing MyClass?

这是为 NSubstitute(以及大多数模拟框架)设计的。

The docs 状态:

For starters, NSubstitute can only work with virtual members of the class, so any non-virtual code in the class will actually execute!

因此,您需要将 virtual 添加到您计划模拟的函数声明中。 或者(根据文档):

If possible, stick to substituting interfaces.