Rhino Mock List约束

时间:2011-09-22 18:25:59

标签: c# unit-testing list rhino-mocks

我试图断言在存根上调用了一个方法。我试图断言的方法被称为IEnumerable<string>。我不关心确切的内容,但我只想测试计数是一定数量。我无法让断言正确,我得到了

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”作为约束。我错过了什么?

2 个答案:

答案 0 :(得分:11)

这里的问题是延迟执行。直到枚举IEnumerable<string>,项目列表才“构建”。由于Rhino.Mocks只记录被调用的内容,因此它永远不会“使用”方法参数,因此,列表永远不会被构建也不会被枚举。如您所见,添加ToList()或ToArray()枚举并构建列表,以便在使用其中一种方法时测试将通过。

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

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

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

答案 1 :(得分:2)

此问题已报告Here。我已经能够通过以下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); 
    }
}

似乎在Rhino Mocks中存在一些问题,当谈到LINQ时:要么将错误报告给Ayende,要么在生产代码中添加ToList()(不是真的推荐)......