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

问题描述 投票:0回答:1

我有一个控制器,其方法是读取配置以确定要调用的其他方法。根据配置,它可以调用零,一个或所有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(),我会得到一个例外。

c# unit-testing mocking moq
1个回答
0
投票

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

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

© www.soinside.com 2019 - 2024. All rights reserved.