开发者

Verifying indirectly called methods with Moq on a mocked object

My app has a ProviderFactory static class that has static开发者_开发知识库 utility methods passing back static instances of things like a logger. The rest of my app then can just grab a/the reference to the logger from anywhere without having to pass in the logger (common design practice).

So, another part of my app, the DbCacheProvider, has methods that make calls to the logger so internally it gets a reference to the logger from the factory and then issues calls to it.

My question is that using Moq, I want to verify methods on the logger are being called by the methods within the DbCacheProvider. I can do this using dependency injection when I pass a mock logger into the DbCacheProvider as a parameter, but I'm not passing the logger in (not do I want to). So, how would I verify the DbCacheProvider is making calls to the logger?


If you don't want to pass the logger in through the constructor you'd need to change your ProviderFactory while running unit tests to return your mocked logger.

Anyway there are a couple of reasons it's often suggested to set up dependency injection:

  1. Your tests are more straightforward and don't involve finagling with custom factories
  2. IoC frameworks like Unity, Ninject and Autofac make it easy to create objects when their dependencies are set up this way. If you set up all of your objects this way, the framework will do all the heavy lifting of creating the right objects and passing them in for you. The dependency injection is done automatically and won't be a burden for you.


Old question without an answer, I had a similar problem and solved it like this:

I have the following sample code and need to verify that not only was a method called but was called with a specific value.

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

public interface ILogFactory
{
    ILog GetLogger();
}

This is the class being tested, where the interface items are being injected:

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");
    }
}

This is obviously a very simplistic view of my actual code, but I needed to verify that Step1 and Step2 are behaving as expected and passed the correct values to the Log, this would mean I also needed to ensure they occurred in the right order. My test:

[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")));
    }
}

Hope this helps.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜