Moq - 验证除了一个方法之外没有调用任何方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Moq - 验证除了一个方法之外没有调用任何方法相关的知识,希望对你有一定的参考价值。

我有一个控制器,其方法是读取配置以确定要调用的其他方法。根据配置,它可以调用零,一个或所有WorkerMethodN()方法。

public class MyController
{
   public virtual bool EntranceMethod()
   {
      // read configuration to determine which methods to call
   }

   public virtual void WorkerMethod1() { ... }
   public virtual void WorkerMethod2() { ... }
   public virtual void WorkerMethod3() { ... }
}

我正在尝试测试这个EntranceMethod(),我的第一个测试是确定配置为空时的行为。当配置什么都不返回时,我想确保没有调用任何WorkerMethodN()方法。

到目前为止我的测试:

[TestMethod]
public void ShouldNotCallAnyMethodsWhenConfigurationReturnsNull()
{
   this.mockConfigurationReader
       .Setup(cr => cr.GetEnabledConfigurations())
       .Returns((IEnumerable<Configuration>)null);

   Mock<MyController> mockController =
      new Mock<MyController>(MockBehavior.Strict, this.mockConfigurationReader.Object);

   mockController.Object.EntranceMethod();

   // todo: verify no additional methods are called
}

当调用invocation failed with mock behavior Strict. All invocations on the mock must have a corresponding setup.时,此调用失败并显示异常:EntranceMethod()

如何使用MockBehavior.Strict并设置我的控制器来调用EntranceMethod()并验证没有其他方法被调用?如果我在.Setup()上调用EntranceMethod(),它将无法运行我想要的实际代码。但如果我不打电话给.Setup(),我会得到一个例外。

答案

仅出于演示目的,假设以下内容

public class Configuration {

}

public interface IConfigurationReader {

    IEnumerable<Configuration> GetEnabledConfigurations();
}

public class MyController {
    private IConfigurationReader configReader;


    public MyController(IConfigurationReader configReader) {
        this.configReader = configReader;
    }

    public virtual bool EntranceMethod() {
        // read configuration to determine which methods to call
        var config = configReader.GetEnabledConfigurations();

        //...code for example purposes only
        if (config != null) {
            WorkerMethod1();
            WorkerMethod2();
            WorkerMethod3();
            return true;
        }

        return false;
    }

    public virtual void WorkerMethod1() {
        //... 
    }
    public virtual void WorkerMethod2() {
        //... 
    }
    public virtual void WorkerMethod3() {
        //... 
    }
}

删除MockBehavior.Strict,启用CallBase = true然后设置并检查其他方法未使用.Verify(......., Times.Never())调用

[TestClass]
public class MyControllerTest {
    [TestMethod]
    public void ShouldNotCallAnyMethodsWhenConfigurationReturnsNull() {
        //Arrange
        var mockConfigurationReader = new Mock<IConfigurationReader>();
        mockConfigurationReader
            .Setup(cr => cr.GetEnabledConfigurations())
            .Returns((IEnumerable<Configuration>)null);

        var mockController = new Mock<MyController>(mockConfigurationReader.Object) {
            CallBase = true
        };

        //Act
        mockController.Object.EntranceMethod();

        //Assert
        // todo: verify no additional methods are called
        mockController.Verify(_ => _.WorkerMethod1(), Times.Never());
        mockController.Verify(_ => _.WorkerMethod2(), Times.Never());
        mockController.Verify(_ => _.WorkerMethod3(), Times.Never());
    }
}

参考Moq Quickstart

以上是关于Moq - 验证除了一个方法之外没有调用任何方法的主要内容,如果未能解决你的问题,请参考以下文章

Moq:验证没有调用方法

Moq:验证是否调用了一个方法

使用 Moq 来验证调用是不是以正确的顺序进行

使用 moq 模拟虚拟只读属性

Moq:设置一个模拟方法在第一次调用时失败,在第二次调用时成功

使用 Moq 确定是不是调用了方法