【问题标题】:Moq - cannot iterate through a hidden IEnumerableMoq - 无法遍历隐藏的 IEnumerable
【发布时间】:2011-08-22 23:07:36
【问题描述】:

我们有一个相当复杂的界面层次结构,我正在努力让 Moq 做我想做的事。

我有一个接口IReservation,它扩展了IRulesReservation,并用另一种类型的新实现隐藏了它的枚举器。

public interface IReservation : IRulesReservation
{
    new IEnumerator<IRoutePart> GetEnumerator();
}

IRulesReservation 扩展IEnumerable

public interface IRulesReservation : IEnumerable<IRulesRoutePart>
{
}

我尝试测试的方法采用IReservation,但在不同的点需要访问IEnumerable&lt;IRulesRoutePart&gt;。我的 Mock 设置如下:

m_mock = new Mock<IReservation>();
m_mock.As<IRulesReservation>().Setup(r => r.GetEnumerator()).Returns(routeParts.Select(rp => (IRulesRoutePart)rp).GetEnumerator());

在示例中,routeParts 是来自Mock&lt;IRouteParts&gt; 对象的IRouteParts 列表,这些对象使用.As&lt;IRulesRoutePart&gt;() 设置。

每当我在我正在测试的函数中遇到一些使用枚举器的代码时,它就会跳过迭代,就好像集合是空的一样。

我的设置有问题吗?还是 Moq 只是无法处理以这种方式隐藏的枚举器?


编辑:我刚刚在 mock 上运行测试代码时注意到的一些奇怪行为:

Assert.That((reservation.Object as IRulesReservation).Count() == 8);
Assert.That((reservation.Object as IEnumerable<IRulesRoutePart>).Count() == 8);

第一行会通过,但第二行会失败。 我尝试更改模拟以专门为IEnumerable&lt;IRulesRoutePart&gt; 设置一个枚举器,但没有效果:

m_mock.As<IEnumerable<IRulesRoutePart>>().Setup(r => r.GetEnumerator()).Returns(routeParts.Select(rp => (IRulesRoutePart)rp).GetEnumerator());

【问题讨论】:

  • 你有没有发现任何其他信息?我遇到了同样的问题并试图解决它。
  • @poindexter12 - 我从来没有设法解决这个问题,但我们后来发现 Moq 会缓存你第一次调用模拟 GetEnumerator() 时获得的枚举器。这意味着后续调用将返回相同的枚举器,这可能是我在后续调用中得到不同行为的原因。要解决此问题,您可以模拟 GetEnumerator() 以返回创建新 Enumerator 的匿名方法,而不是像上面的示例代码中那样直接调用 GetEnumerator() 的具体实现。祝你好运!

标签: c# .net mocking moq


【解决方案1】:

您的设置返回的对象是否真的有数据?这可能是你的问题。

【讨论】:

  • 确实如此,示例中的 routeParts 是来自 Mock 的 IRouteParts 列表,它们也设置为 .As()。
  • 您必须在某个地方填充设置返回的数据。您在哪里创建包含虚假数据的 irouteparts 填充列表?
  • 不确定它的相关性,但 IRouteParts 列表是预先创建的,并保存在该示例中名为 routeParts 的变量中。
  • 如果您在上述设置调用之前检查路线部分,它是否有值?是不是只有调用后return是空的?
  • 是的,在该行设置断点显示列表已填充。设置完成并调用生产代码后,迭代将表现为空。
猜你喜欢
  • 2011-09-17
  • 2011-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-23
  • 1970-01-01
  • 2019-03-22
相关资源
最近更新 更多