【问题标题】:NSubstitute ForPartsOf mock all methods except one?NSubstitute ForPartsOf 模拟除一个以外的所有方法?
【发布时间】:2019-09-18 14:31:40
【问题描述】:

使用 NSubstitute,可以使用 Substitute.ForPartsOf<T>() 仅模拟特定方法。但这将默认调用真实方法,除非您专门配置要模拟的方法,例如mySubstitute.Configure().MyMethod().Returns(/*whatever*/).

我想做相反的事情:创建一个默认模拟所有方法的替代品,然后指定一个特定的方法来进行真正的调用。

有没有一种干净的方法可以做到这一点?

我能想到的最佳方法是(未经测试):

MyClass realObj = new MyClass();
var subst = Substitute.For<MyClass>();
subst.MyMethod().Returns(realObj.MyMethod());

我想我正在寻找这样做的捷径:

var subst = Substitute.ForPartsOf<MyClass>();
// Mock all methods except MyMethod:
subst.Configure().MyOtherMethod().Returns(/*whatever*/)
subst.Configure().MyThirdMethod().Returns(/*whatever*/)
// ...
subst.Configure().MyLastMethod().Returns(/*whatever*/)

【问题讨论】:

  • 想一想,我认为我建议的方法行不通。 realObj.MyMethod() 调用将对realObj 的真实方法进行任何内部调用,而不是调用subst 上的那些,对吧?

标签: c# mocking nsubstitute


【解决方案1】:

您可以选择调用普通 sub 的基本实现。

public class MyClass
{
    public virtual int MyMethod() => 42;
    public virtual int MyMethod1() => 1;
    public virtual int MyMethod2() => 2;
    public virtual int MyMethod3() => 3;
}


[Fact]
public void Sample() {
    var sub = Substitute.For<MyClass>();

    sub.When(x => x.MyMethod()).CallBase();            

    // Returns from base:
    Assert.Equal(42, sub.MyMethod());
    // Other methods mocked (return default value for int):
    Assert.Equal(0, sub.MyMethod1());
    Assert.Equal(0, sub.MyMethod2());
    Assert.Equal(0, sub.MyMethod3());
}

请记住免责声明,MyClass 上的所有方法都应该是 virtual,以便 NSubstitute 能够使用它们。 :)

【讨论】:

  • 对,当然!谢谢!再虚拟,我已经了解到,一个方法实现一个接口方法是不够的。事实上,这无关紧要。相反,虚拟是相关的。 :-)
  • @KjellRilbe 下面是对virtual/interface 要求的解释:nsubstitute.github.io/help/how-nsub-works 成员需要是可覆盖的,以便可以用替代实现替换它们。
  • 谢谢,但我已经明白了。我只是没有好好思考。呃...不过可能对其他人有帮助,所以感谢您添加该评论。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-17
  • 2021-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多