【问题标题】:When using Moq, are mocked interfaces implemented methods supposed to execute?使用 Moq 时,模拟接口是否实现了应该执行的方法?
【发布时间】:2016-08-15 17:44:50
【问题描述】:

我是使用 Moq 的新手,大约 5 年没有进行单元测试。很多东西都变了。

我正试图围绕基础知识。

我有一个界面。

public interface ILogger
{
    void Log(string message)
}

而这个接口的实现方式如下。

public class MyLogger : ILogger
{
    public virtual void Log(string message)
    {
        StaticClass.StaticMethodNotToBeCalled<ILogger>().Log(message);
    }
}

我正在测试以下逻辑。

public class MyClass
{
    public MyMethod(int z)
    {
        var logger = new MyLogger();

        if(z == 5) 
        {
           logger.Log("it is true");

           return true;
        }

        logger.Log("it is false);

        return false;
    }
}

我的测试如下所示。

[TestMethod]
public void Test_MyMethod()
{
    var mock = new Mock<ILogger>();

    mock.Setup(y => y.Log(It.IsAny<string>()).Verifiable();

    var o = new MyClass();

    var result = o.MyMethod(5);

    Assert.IsTrue(result);        

    mock.Verify();

}

我遇到的问题是在 ILogger 接口的实现中调用的静态方法。

我猜我只是不太了解 mock 到底应该是什么。

我想做的是,任何时候 ILogger.Log 都会被覆盖并且不会调用该静态方法。

这可能吗?

我是不是走错路了?

【问题讨论】:

    标签: c# unit-testing tdd moq


    【解决方案1】:

    您正在创建一个基于 ILogger 接口的 Mock,但您没有将 Mock 注入到您的 MyClass 实例中。当MyClass 执行时,它使用Logger 的实例而不是你的ILogger 模拟。

    为你的班级考虑这样的事情:

    public class MyClass
    {
    
        private ILogger logger;
        public MyClass(ILogger loggerInstance)
        {
            logger=loggerInstance;
        }
        public MyMethod(int z)
        {
    
            if(z == 5) 
            {
               logger.Log("it is true");
    
               return true;
            }
    
            logger.Log("it is false);
    
            return false;
        }
    }
    

    请注意,在 MyClass 的构造函数中,您现在接受一个实现 ILogger 接口的类的实例。这允许您注入模拟对象来代替实际的具体 Logger:

    [TestMethod]
    public void Test_MyMethod()
    {
        var mock = new Mock<ILogger>();
    
        mock.Setup(y => y.Log(It.IsAny<string>()).Verifiable();
    
        var o = new MyClass(mock.Object);
    
        var result = o.MyMethod(5);
    
        Assert.IsTrue(result);        
    
        mock.Verify();
    
    }
    

    依赖注入是您在场景中缺少的概念。在许多情况下,编写可单元测试的代码是必不可少的。

    【讨论】:

    • 嘿,谢谢这个作品。我想我很沮丧,嘲笑本质上不是更具全球性,但这很好。我最初避免在构造函数中做任何事情,因为这个实例中的 Class 是一个 Controller,但是这种模式仍然可以正常工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-07
    • 1970-01-01
    • 2017-11-02
    • 2017-10-23
    • 1970-01-01
    相关资源
    最近更新 更多