我正在尝试使用Rhino Mocks来模拟下面的lambda,但是一直打砖墙
var result = rep.Find<T>(x => (x as IEntity).ID == (entity as IEntity).ID).FirstOrDefault();
有什么想法吗?
答案 0 :(得分:5)
在单元测试中,您有被测系统(SUT)及其协作者。模拟的目标是通过您完全控制的内容替换协作者。这样你就可以设置不同的测试用例,你可以专注于测试被测系统的行为,而不是其他任何测试用例。
在这种情况下,我假设rep
对象是SUT。您传递给SUT的Find
方法的lambda可以被视为协作者。既然你已经可以完全控制那个lambda,那么尝试使用Rhino Mocks来模拟它并没有多大意义。
我将尝试给出一个涉及Rhino Mocks和lambdas的单元测试示例;-)这是一个示例测试,它创建一个始终返回false的谓词存根,并且实际验证Find
方法调用了谓词:
[Test]
public void Find_returns_nothing_if_predicate_always_false()
{
var predicateStub = MockRepository.GenerateStub<Func<Entity,bool>>();
predicateStub.Stub(x => x(Arg<Entity>.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<Entity>.Is.Anything));
}
当然,就像你自己的例子一样,你真的不需要Rhino Mocks。 lambda语法的重点是使得提供就地实现变得容易:
[Test]
public void Find_returns_nothing_if_predicate_always_false()
{
bool predicateCalled = false;
Func<Entity,bool> 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");
}
答案 1 :(得分:5)
找到我追求的答案
repository.Expect(action => action.Find<Entity>(x => x.ID == 0))
.IgnoreArguments()
.Return(entities)
.Repeat
.Any();
答案 2 :(得分:0)
这样我们就不能出来了......因为IgnoreArguments(),它永远不会进入并看到参数的值,我们将通过。 但是这种方法的主要问题是编写AssertWasCalled(一些lambda表达式)是不可能的,因为现在在Assert部分它显示错误,如ExpectaionViolationException未被用户代码处理