在犀牛嘲笑中嘲弄lambda

Cop*_*ill 4 c# lambda rhino-mocks mocking

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

var result = rep.Find<T>(x => (x as IEntity).ID == (entity as IEntity).ID).FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

Wim*_*nen 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));
}
Run Code Online (Sandbox Code Playgroud)

当然,就像你自己的例子一样,你真的不需要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");
}
Run Code Online (Sandbox Code Playgroud)


Cop*_*ill 5

找到了我追求的答案

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

  • 这与我所得到的结论相同,但不幸的是,它仍然在我的单元测试能力上留下了一个漏洞(而且我认为是你的).如果我有一个需要使用不同参数对repository.Find方法进行多次调用的测试,我该如何为它设置模拟?我需要模拟一个Expression <Func <T,bool >>,并且在设置mock时为表达式创建的引用不会等同于稍后在代码中创建的Expression,因为它将是一个新的引用一个等效的表达式. (3认同)