【问题标题】:Mocking objects with Moq when constructor has parameters当构造函数有参数时使用 Moq 模拟对象
【发布时间】:2011-11-16 21:36:38
【问题描述】:

我有一个我正在尝试使用 moq 模拟的对象。对象的构造函数有必要的参数:

public class CustomerSyncEngine {
    public CustomerSyncEngine(ILoggingProvider loggingProvider, 
                              ICrmProvider crmProvider, 
                              ICacheProvider cacheProvider) { ... }
}

现在我正在尝试使用 moq 的 v3“设置”或 v4“Mock.Of”语法为该对象创建模拟,但无法解决这个问题......我正在尝试的一切都没有验证。这是我到目前为止所拥有的,但最后一行是给我一个真实的对象,而不是模拟。我这样做的原因是因为我在 CustomerSyncEngine 上有要验证的方法正在被调用...

// setup
var mockCrm = Mock.Of<ICrmProvider>(x => x.GetPickLists() == crmPickLists);
var mockCache = Mock.Of<ICacheProvider>(x => x.GetPickLists() == cachePickLists);
var mockLogger = Mock.Of<ILoggingProvider>();

// need to mock the following, not create a real class like this...
var syncEngine = new CustomerSyncEngine(mockLogger, mockCrm, mockCache);

【问题讨论】:

  • 你能提供一个你希望验证被调用的示例方法吗?
  • 因此,如果我依赖于类而不是接口,我什至必须模拟它们的依赖关系,这会递归地下降。最后,我不得不使用一些接口来保持我的代码可测试,即使我的代码中不需要这些接口。我认为太多的接口比模拟具体类更臭……

标签: moq


【解决方案1】:

将最后一行改为

var syncEngine = new Mock<CustomerSyncEngine>(mockLogger, mockCrm, mockCache).Object;

它应该可以工作

【讨论】:

  • 不确定这条评论如何适用于我的回答?
  • 因为这会导致编译错误,因为 mockLogger 和其他人会抛出他们没有 Object 属性的异常
  • 因为 OP 使用 Mock.Of() 创建 logger、crm 和缓存类型的模拟,所以返回的对象返回为 T,而不是 Mock。因此,mockLogger.Object 等在将它们提供给 CustomerSyncEngine 的 Mock 时不需要,正如@JustinPihony 提到的那样,应该向您显示设计时错误。
  • @suhas 他不应该是new Mock&lt;CustomerSyncEngine&gt;(new object[]{mockLogger, mockCrm, mockCache}).Object;
  • @GiriB 不需要,但可能,因为模拟是使用参数定义的。公共模拟(参数对象[] args)
【解决方案2】:

最后一行是给你一个真实的实例,因为你使用的是 new 关键字,而不是模拟 CustomerSyncEngine。

你应该使用Mock.Of&lt;CustomerSyncEngine&gt;()

Mocking Concrete 类型的唯一问题是 Moq 需要一个公共默认构造函数(没有参数),或者您需要使用构造函数 arg 规范创建 Moq。 http://www.mockobjects.com/2007/04/test-smell-mocking-concrete-classes.html

最好的办法是右键单击您的类并选择提取界面。

【讨论】:

  • 关于这个问题,另一种方法是使用 AutoMocking 容器。我最喜欢的是 Machine.Fakes 和 Machine.Specifications,使用自动模拟容器可以更轻松地测试较小的表面积。假设 Andrew 需要测试 CustomerSyncEngine 中的一个方法,该方法仅使用 ICrmProvider,必须为所有 3 个接口提供传统的模拟实现,而自动模拟容器只允许您提供一个。
猜你喜欢
  • 2011-02-27
  • 2013-11-17
  • 1970-01-01
  • 2012-04-28
  • 2017-11-04
  • 2014-06-03
  • 2011-03-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多