验证在模拟对象上使用Moq间接调用的方法

时间:2011-09-16 13:49:22

标签: moq

我的应用程序有一个ProviderFactory静态类,它使用静态实用程序方法传回像记录器这样的静态实例。然后,我的应用程序的其余部分可以从任何地方获取/记录器的引用,而无需传入记录器(通用设计实践)。

因此,我的应用程序的另一部分DbCacheProvider具有调用记录器的方法,因此在内部它从工厂获取对记录器的引用,然后发出对它的调用。

我的问题是使用Moq,我想验证记录器上的方法是由DbCacheProvider中的方法调用的。当我将模拟记录器作为参数传递给DbCacheProvider时,我可以使用依赖注入来执行此操作,但是我没有传递记录器(不是我想要的)。那么,我如何验证DbCacheProvider是否正在调用记录器?

2 个答案:

答案 0 :(得分:0)

如果您不想通过构造函数传递记录器,则需要在运行单元测试时更改ProviderFactory以返回模拟记录器。

无论如何,有几个原因经常建议设置依赖注入:

  1. 您的测试更直接,不涉及与定制工厂的联系
  2. Unity,Ninject和Autofac等IoC框架可以在以这种方式设置依赖项时轻松创建对象。如果以这种方式设置所有对象,框架将完成创建正确对象并将它们传递给您的所有繁重工作。依赖注入是自动完成的,不会给你带来负担。

答案 1 :(得分:0)

老问题没有答案,我有类似的问题,并解决了这个问题:

我有以下示例代码,需要验证调用的方法不仅是使用特定值调用的方法。

public interface ILog
{
    void Info(string message);
}

public interface ILogFactory
{
    ILog GetLogger();
}

这是正在测试的类,其中正在注入接口项:

public class NewAction
{
    readonly ILogFactory _logger;

    public NewAction(ILogFactory logger)
    {
        _logger = logger;
    }

    public void Step1()
    {
        _logger.GetLogger().Info("Step 1");
    }

    public void Step2()
    {
        _logger.GetLogger().Info("Step 2");
    }
}

这显然是我实际代码的一个非常简单的视图,但我需要验证Step1和Step2是否按预期运行并将正确的值传递给Log,这意味着我还需要确保它们出现在右侧订购。我的测试:

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        // Arrange
        var log = new Mock<ILog>();

        var factory = new Mock<ILogFactory>();
        factory.Setup(l => l.GetLogger()).Returns(log.Object);

        // Act
        var action = new NewAction(factory.Object);
        action.Step1();
        action.Step2();

        // Assert
        factory.Verify(l => l.GetLogger());
        log.Verify(l => l.Info(It.Is<string>(s => s == "Step 1")));
        log.Verify(l => l.Info(It.Is<string>(s => s == "Step 2")));
    }
}

希望这有帮助。