避免在单元测试 (NUnit) 中使用 运行 函数

Avoid running function within Unit Test (NUnit)

说我有一个 class:

public class SomeClass {

   public Model _model;

   public SomeClass() {
     _model = new Model(); 
   }

   public void Foo() {
     _model.DoSomethingHeavy();
   }

}

还有一个测试:

[TestFixture]
public class SomeClassTest {

  [Test]
  public void TestFooCalledSomethingHeavy() {
    SomeClass someClass = NSubstitute.Substitute.For<SomeClass>();  
    someClass.Foo();        
    someClass._model.Received().DoSomethingHeavy();
  }
}

我正在尝试测试 someClass.Foo();称为 _model.DoSomethingHeavy() 但我实际上并不希望 DoSomethingHeavy 到 运行。我该怎么做?或者这是错误的方法?

要使用 NSubstitute 覆盖方法的行为,该方法需要是接口或虚方法的一部分。

首先确保方法 DoSomethingHeavy 标记为虚拟或创建 Model class

的接口(更好 -> 提供更多测试可能性)
public interface IModel
{
    void DoSomethingHeavy();
}

在您的 Model class

中实现接口
public class Model : IModel
{
    public void DoSomethingHeavy()
    {
        // heavy staff
    }
}

然后,对于测试非常重要 -> 消除在 SomeClass

之外创建 Model 实例的责任
public class SomeClass 
{
    public Model _model { get; private set; }

    // Constructor will sure, that class get an instance of IModel
    public SomeClass(IModel model) 
    {
        _model = model; 
    }

    public void Foo() 
    {
        _model.DoSomethingHeavy();
    }
}

现在您可以伪造 IModel 并检查 DoSomethingHeavy 方法在没有 运行 实际实现的情况下执行。

因为 SomeClass 在测试中 class,你不需要模拟它 - 你将测试那个 class 的行为。

[Test]
public void TestFooCalledSomethingHeavy() 
{
    // Arrange
    IModel fakeModel = Substitute.For<IModel>();
    SomeClass someClass = new SomeClass(fakeModel); 

    // Act 
    someClass.Foo();  

    // Assert      
    fakeModel.Received().DoSomethingHeavy();
}