【问题标题】:How to mock ReadOnlyCollection<T> in Rhino Mocks?如何在 Rhino Mocks 中模拟 ReadOnlyCollection<T>?
【发布时间】:2013-09-29 18:24:48
【问题描述】:

我在我的单元测试中使用 rhino mock,我正在尝试使用以下代码创建一个 mock:

var userDetails = MockRepository.GenerateMock<ReadOnlyCollection<UserDetails>>();

但是当我运行单元测试时,出现以下错误:

Can not instantiate proxy of class: 
System.Collections.ObjectModel.ReadOnlyCollection`
1[[SolutionName.FolderName,]].
Could not find a parameterless constructor.

我在网上搜索并找到了类似的问题和解决方案,其中一个是使用 SetupGet() 方法针对 moq 的,但我不知道这在 rhino mocks 中是什么等价物。 (UserDetails 类确实有一个无参数构造函数)如何为 ReadOnlyCollection 创建存根/模拟?

【问题讨论】:

  • 为什么需要模拟它?我想我会创建一个实例并根据需要进行设置。用模拟来赢得胜利并不多。

标签: c# unit-testing rhino-mocks


【解决方案1】:

您可以将任何构造函数参数传递给GenerateMock

var inner = new List<UserDetails>();
var userDetails = MockRepository.GenerateMock<ReadOnlyCollection<UserDetails>>(inner);

您可能需要考虑在测试中创建ReadOnlyCollection 的实例并从其他方法调用中返回它,这比模拟适当的方法要简单得多。

【讨论】:

  • 它通过了最初的错误,但现在当我尝试对它做任何事情时,我得到'无效呼叫,最后一次呼叫已被使用或没有呼叫(确保您正在呼叫一个虚拟(C#)/可覆盖(VB)方法)。 - 我应该让我调用虚拟的方法只是让犀牛模拟可以使用它吗?我刚刚意识到这是一个静态类,所以我不能大声笑
  • @Theomax - 不看代码很难判断,但看看ReadOnlyCollection,大多数方法都是非虚拟的,所以你不能使用 rhino 模拟来模拟它们。如果您使用的是 .Net 4.5,则可以改用 IReadonlyCollection,但是我会在测试中构建您需要的任何测试数据,而不是尝试模拟框架类。
【解决方案2】:

不确定您是否可以使用 Rhino Mock 做到这一点。问题是 ReadOnlyCollection 不是接口,也不包含虚拟方法,开源模拟框架可以使用这些方法。

由于ReadOnlyCollection 实现了IList,您可以尝试在此 SO 问题中找到的建议方法

How to mock a private readonly IList<T> property using moq

基本上将 IList 集合用作公共属性,但将基础列表设为私有,因此您仍然可以获得只读体验。因此,在您的测试中,您可以使用:

var userDetails = MockRepository.GenerateMock&lt;IList&lt;UserDetails&gt;&gt;();

如果您真的想要模拟 ReadOnlyCollection,则需要购买 TypeMock 或 JustMock。或者,获取带有 Update 2 的 Visual Studio 2012 Premium,您可以在其中使用 MS Fakes 模拟框架。

编辑: Lee 的回答比我的要高效得多:) 我建议改为。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-27
    • 1970-01-01
    相关资源
    最近更新 更多