简体   繁体   English

在犀牛嘲笑中嘲弄lambda

[英]Mocking lambda in rhino mocks

I am trying to use Rhino Mocks to mock the following lambda, but keep hitting a brick wall 我正在尝试使用Rhino Mocks来模拟下面的lambda,但是不断碰到一堵砖墙

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

Any ideas? 有任何想法吗?

In a unit test, you have the system under test (SUT) and its collaborators. 在单元测试中,您有被测系统(SUT)及其协作者。 The goal of mocking is to replace the collaborators by something that you have full control over. 模拟的目标是通过您完全控制的内容替换协作者。 That way you can set up different test cases and you can focus on testing just the behavior of the system under test, and nothing else. 这样您就可以设置不同的测试用例,并且可以专注于测试被测系统的行为,而不是其他任何测试用例。

In this case, I assume the rep object is the SUT. 在这种情况下,我假设rep对象是SUT。 The lambda that you pass to the SUT's Find method could be considered a collaborator. 传递给SUT的Find方法的lambda可以被视为协作者。 Since you already have full control over that lambda, it doesn't really make sense to try to mock it with Rhino Mocks. 既然你已经可以完全控制那个lambda,那么尝试使用Rhino Mocks来模拟它并没有多大意义。

I'll try to give an example of unit test involving Rhino Mocks and lambdas anyway ;-) This is an example test which creates a predicate stub that always returns false, and which verifies that the Find method actually invoked that predicate: 我将尝试给出一个涉及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));
}

Of course, as in your own example, you don't really need Rhino Mocks here. 当然,就像你自己的例子一样,你真的不需要Rhino Mocks。 The whole point of the lambda syntax is to make it easy to provide an implementation in-place: 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");
}

Found the answer I was after 找到了我追求的答案

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

this way we can't come out..because due to the IgnoreArguments(),it will never go inside and see the value of arguments and we will pass through. 这样我们就无法出来了......因为IgnoreArguments(),它永远不会进入并看到参数的值,我们将通过。 But the major problem with this approach is writing the AssertWasCalled(some lambda expression) is not possible because now in the Assert part it is showing error like ExpectaionViolationException was unhandled by user code 但是这种方法的主要问题是编写AssertWasCalled(一些lambda表达式)是不可能的,因为现在在Assert部分它显示错误,如ExpectaionViolationException未被用户代码处理

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM