c# - 时间:2019-04-01 标签:c#mock interface vs mock class
问题描述
我是 .net 中的 moq 框架的新手。根据我的在线研究,似乎有两种方法可以利用这个框架。要么模拟接口,要么模拟一个具体的类。似乎在模拟具体类时,只能virtual
模拟方法。就我而言,我只想模拟一个实现接口的类的几个方法。
例如,如果我们有以下内容:
public interface Ifoo
{
int Bar();
}
public class Foo : Ifoo
{
public virtual int Bar()
{
return 0;
}
}
public class Client
{
public Client(Ifoo foo)
{
var temp = foo.Bar();
}
}
现在,如果我需要对客户端进行单元测试,我需要在 ctor 中传递一个模拟的 Ifoo 对象。在这种情况下,我应该这样做:
var mock = new Mock<Ifoo>();
或者
var mock = new Mock<Foo>();
这对我的情况有影响吗?模拟接口与模拟类的优缺点是什么?对我来说,模拟接口总是一个更好的解决方案,因为模拟一个类只能模拟virtual
方法。
解决方案
以下是需要考虑的几点:
- 您的客户使用 IFoo,所以这就是您应该模拟的内容。
- 如果您的客户端使用具体类,您应该考虑重构客户端以使用接口或抽象类,而不是遵守 SOLID 原则。
- 如果您的客户端在测试期间使用 Foo 的模拟而不是接口,并且它依赖于该测试中的一些非模拟行为,那么您实际上并没有编写单元测试,因为您正在测试多个行为单元。
- 如果您的客户端在测试期间没有使用任何非模拟行为,那么您也可以只传递接口的模拟。
tldr:类应该使用接口或抽象类而不是具体类。测试应该模拟接口或抽象类而不是具体类。
推荐阅读
- javascript - 如何获得一年的第一天?
- machine-learning - 在 PyTorch 中对深度学习模型进行评估(例如测试、验证)以便正确保存检查点的正确方法是什么?
- python - iTerm2 Python API:如何运行命令并捕获结果
- jupyter-notebook - 更新仅显示在 Jupyter Notebooks 中的环境变量
- encoding - 如何为一系列整数提供 VByte 代码?
- powershell - Stop-WebAppPool 不停止池,同时我可以在 IIS 面板中停止它
- javascript - Typescript 在 d.ts 中动态声明命名导出
- ffmpeg - FFMPEG - 从本地流中每隔 n 秒保存一次快照
- terraform - 无法显示 tf 状态
- python - Flask 中的多处理,具有永远运行的功能