使用 Moq 时,是否应该执行模拟接口实现的方法?
When using Moq, are mocked interfaces implemented methods supposed to execute?
我刚开始使用 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 它被覆盖并且不调用该静态方法。
这可能吗?
我是不是做错了?
您正在创建一个基于 ILogger
接口的 Mock,但您没有将 Mock 注入到您的 MyClass
实例中。当 MyClass
执行时,它使用 Logger
的实例而不是你的 ILogger
模拟。
为您的 class 考虑这样的事情:
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
接口的 class 实例。这允许您注入模拟对象来代替实际的具体记录器:
[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();
}
依赖注入 是您在场景中缺少的概念。在许多情况下,编写可单元测试的代码是必不可少的。
我刚开始使用 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 它被覆盖并且不调用该静态方法。
这可能吗?
我是不是做错了?
您正在创建一个基于 ILogger
接口的 Mock,但您没有将 Mock 注入到您的 MyClass
实例中。当 MyClass
执行时,它使用 Logger
的实例而不是你的 ILogger
模拟。
为您的 class 考虑这样的事情:
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
接口的 class 实例。这允许您注入模拟对象来代替实际的具体记录器:
[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();
}
依赖注入 是您在场景中缺少的概念。在许多情况下,编写可单元测试的代码是必不可少的。