【发布时间】:2014-02-23 00:17:41
【问题描述】:
我想测试我班级的方法 A,但不调用通常由 A 调用的实际方法 B。那是因为 B 有很多外部交互,我现在不想测试。
我可以为 B 调用的所有服务创建模拟,但这是相当多的工作。我宁愿只是模拟 B 并让它返回示例数据。
这可能与 Moq 框架有关吗?
【问题讨论】:
我想测试我班级的方法 A,但不调用通常由 A 调用的实际方法 B。那是因为 B 有很多外部交互,我现在不想测试。
我可以为 B 调用的所有服务创建模拟,但这是相当多的工作。我宁愿只是模拟 B 并让它返回示例数据。
这可能与 Moq 框架有关吗?
【问题讨论】:
是的,有一个陷阱!
您必须确保方法 B 是虚拟的并且可以被覆盖。
然后,将模拟设置为在未提供设置时调用基本方法。然后你设置B,但不要设置A。因为A没有设置,实际的实现会被调用。
var myClassMock = new Mock<MyClass>();
myClassMock.Setup(x => x.B()); //mock B
myClassMock.CallBase = true;
MyClass obj = myClassMock.Object;
obj.A(); // will call the actual implementation
obj.B(); // will call the mock implementation
在幕后,Moq 将动态创建一个扩展 MyClass 并覆盖 B 的类。
【讨论】:
virtual 方法B 是protected internal 或public 将是最简单的。
MyClass 中定义的方法,除非提供了明确的设置。如果您没有调用CallBase = true,那么无论是否提供了显式设置,Moq 都会调用每个虚拟方法的假实现。
protected internal virtual 没有出现在模拟设置中?