Rhino 模拟列表约束

发布于 2024-12-06 04:29:20 字数 721 浏览 0 评论 0原文

我试图断言在存根上调用了一个方法。我尝试断言调用的方法采用 IEnumerable。我不关心具体的内容,但我只是想测试计数是否是某个数字。我无法得到正确的断言,我知道

Rhino.Mocks.Exceptions.ExpectationViolationException : Bob.DoThings(collection count equal to 10); Expected #1, Actual #0.

DoThings() 确实被调用了......我只是无法得到正确的约束......

var myBob= MockRepository.GenerateStub<Bob>();
var countConstraint =   Rhino.Mocks.Constraints.List.Count(Rhino.Mocks.Constraints.Is.Equal(10));

// execution code....
Joe myJoe = new Joe(myBob);
myJoe.MethodThatShouldCallDoThingWith10();

myBob.AssertWasCalled(s => s.DoThings(null), o => Constraints(countConstraint));

我还尝试添加“IgnoreArguments”作为约束。我缺少什么?

I'm trying to asssert that a method was called on a stub. The method I'm trying to assert was called takes an IEnumerable<string>. I don't care about the exact contents, but I just want to test that the count is a certain number. I can't get the assertion correct, I get

Rhino.Mocks.Exceptions.ExpectationViolationException : Bob.DoThings(collection count equal to 10); Expected #1, Actual #0.

I know that DoThings() is indeed being called... I just can't get the constraint correct..

var myBob= MockRepository.GenerateStub<Bob>();
var countConstraint =   Rhino.Mocks.Constraints.List.Count(Rhino.Mocks.Constraints.Is.Equal(10));

// execution code....
Joe myJoe = new Joe(myBob);
myJoe.MethodThatShouldCallDoThingWith10();

myBob.AssertWasCalled(s => s.DoThings(null), o => Constraints(countConstraint));

I've also tried adding "IgnoreArguments" as a constraint. What am I missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

↙厌世 2024-12-13 04:29:20

这里的问题是延迟执行。直到 IEnumerable 被枚举后,项目列表才被“构建”。由于Rhino.Mocks只记录被调用的内容,因此它从不“使用”方法参数,因此从未构建或枚举列表。正如您所看到的,添加 ToList() 或 ToArray() 会枚举并构建列表,因此如果您使用这些方法之一,测试就会通过。

一种解决方法是获取传递给该方法的列表并对其进行检查:

var list = (IEnumerable<int>) myBob.GetArgumentsForCallsMadeOn(b => b.DoThings(null))[0][0];
Assert.AreEqual(10, list.Count());

此测试通过并且不需要对代码进行任何更改。

The issue here is with deferred execution. It's not until the IEnumerable<string> is enumerated that the list of items is "built". Since Rhino.Mocks just records what gets called, it never "uses" the method arguments and therefore, the list is never built nor enumerated. As you've seen, adding a ToList() or ToArray() enumerates and builds the list so the test will pass if you use one of those methods.

One workaround is to grab the list that was passed to the method and do your check on that:

var list = (IEnumerable<int>) myBob.GetArgumentsForCallsMadeOn(b => b.DoThings(null))[0][0];
Assert.AreEqual(10, list.Count());

This test passes and doesn't require any changes to your code.

枯叶蝶 2024-12-13 04:29:20

此问题已在此处报告。我已经能够用以下 Bob 和 Joe 重现这个问题:

public interface Bob
{ void DoThings(IEnumrable<int> list); }

public class Joe
{
    private readonly Bob bob;

    public Joe(Bob bob)
    { this.bob = bob; }

    public void MethodThatShouldCallDoThingWith10()
    { 
          var values = Enumerable.Range(1, 100).Where(x => x > 0 && x < 11);
          bob.DoThings(values); 
    }
}

当涉及到 LINQ 时,Rhino Mocks 似乎确实存在一些问题:要么将 bug 报告给 Ayende 或在您的生产代码中添加 ToList() (不真正推荐)...

This problem was alredy reported Here. I've been able to reproduce this problem with the following Bob and Joe:

public interface Bob
{ void DoThings(IEnumrable<int> list); }

public class Joe
{
    private readonly Bob bob;

    public Joe(Bob bob)
    { this.bob = bob; }

    public void MethodThatShouldCallDoThingWith10()
    { 
          var values = Enumerable.Range(1, 100).Where(x => x > 0 && x < 11);
          bob.DoThings(values); 
    }
}

It seems there's some problem in Rhino Mocks after all, when it comes to LINQ: either report the bug to Ayende or add ToList() in your production code (not really recommended)...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文