在犀牛嘲笑中嘲弄lambda

我正在尝试使用Rhino Mocks来模拟下面的lambda,但是不断碰到一堵砖墙

var result = rep.Find(x => (x as IEntity).ID == (entity as IEntity).ID).FirstOrDefault(); 

有任何想法吗?

在unit testing中,您有被测系统(SUT)及其协作者。 嘲笑的目标是用你完全控制的东西取代合作者。 这样您就可以设置不同的测试用例,并且可以专注于测试被测系统的行为,而不是其他任何测试用例。

在这种情况下,我假设rep对象是SUT。 您传递给SUT的Find方法的lambda可以被视为协作者。 既然你已经完全控制了这个lambda,那么尝试使用Rhino Mocks来模拟它并没有多大意义。

我将尝试给出一个涉及Rhino Mocks和lambdas的unit testing示例;-)这是一个示例测试,它创建一个始终返回false的谓词存根,并validationFind方法实际调用了该谓词:

 [Test] public void Find_returns_nothing_if_predicate_always_false() { var predicateStub = MockRepository.GenerateStub>(); predicateStub.Stub(x => x(Arg.Is.Anything)).Return(false); var repository = new Repository(); var entities = repository.Find(predicateStub); Assert.AreEqual(0, entities.Count(), "oops, got results while predicate always returns false"); predicateStub.AssertWasCalled(x => x(Arg.Is.Anything)); } 

当然,就像你自己的例子一样,你真的不需要Rhino Mocks。 lambda语法的重点是使得提供就地实现变得容易:

 [Test] public void Find_returns_nothing_if_predicate_always_false() { bool predicateCalled = false; Func predicate = x => { predicateCalled = true; return false; }; var repository = new Repository(); var entities = repository.Find(predicate); Assert.AreEqual(0, entities.Count(), "oops, got results while predicate always returns false"); Assert.IsTrue(predicateCalled, "oops, predicate was never used"); } 

找到了我追求的答案

 repository.Expect(action => action.Find(x => x.ID == 0)) .IgnoreArguments() .Return(entities) .Repeat .Any(); 

这样我们就不能出来了……因为IgnoreArguments(),它永远不会进入并看到参数的值,我们将通过。 但是这种方法的主要问题是编写AssertWasCalled(一些lambda表达式)是不可能的,因为现在在Assert部分它显示错误,如ExpectaionViolationException未被用户代码处理