在 rhino 模拟中模拟 lambda

发布于 2024-08-28 12:13:57 字数 189 浏览 4 评论 0原文

我正在尝试使用 Rhino Mocks 来模拟以下 lambda,但一直碰壁

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

有什么想法吗?

I am trying to use Rhino Mocks to mock the following lambda, but keep hitting a brick wall

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

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

懵少女 2024-09-04 12:13:57

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

在本例中,我假设 rep 对象是 SUT。您传递给 SUT 的 Find 方法的 lambda 可以被视为协作者。由于您已经完全控制了该 lambda,因此尝试使用 Rhino Mocks 来模拟它并没有多大意义。

无论如何,我将尝试给出一个涉及 Rhino Mocks 和 lambda 的单元测试示例;-) 这是一个示例测试,它创建一个始终返回 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");
}

In a unit test, you have the system under test (SUT) and its collaborators. 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. The lambda that you pass to the SUT's Find method could be considered a collaborator. Since you already have full control over that lambda, it doesn't really make sense to try to mock it with 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:

[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. The whole point of the lambda syntax is to make it easy to provide an implementation in-place:

[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");
}
梓梦 2024-09-04 12:13:57

找到了我想要的答案

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

Found the answer I was after

repository.Expect(action => action.Find<Entity>(x => x.ID == 0))
          .IgnoreArguments()
          .Return(entities)
          .Repeat
          .Any();
别挽留 2024-09-04 12:13:57

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

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.
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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文