【问题标题】:NSubstitute ForPartsOf calling concrete implementation event when substitutedNSubstitute ForPartsOf 在替换时调用具体实现事件
【发布时间】:2017-11-23 11:55:55
【问题描述】:

我有以下课程:

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 有效地将我的类子类化并替换了标记的方法;所以我这样做了:

[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,看起来像这样的结构可以解决问题(尽管它确实使用了听起来很模糊的短语“玩得安全”):

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

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

【问题讨论】:

  • 如果在函数声明中添加virtual 会发生什么?
  • ... 突然间一切都到位了 - 谢谢!

标签: c# unit-testing subclass nsubstitute


【解决方案1】:

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

The docs 状态:

对于初学者,NSubstitute 只能与 类,因此类中的任何非虚拟代码都会实际执行!

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

如果可能,坚持替换接口。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多