【问题标题】:Rhino Mocks 'Expect' with FakeItEasyRhino 用 FakeItEasy 模拟“期望”
【发布时间】:2013-11-20 12:55:41
【问题描述】:

我有一个数据库操作对象作为我的 UUT(被测单元)的依赖项。因此,我想让它成为一个严格的模拟,因为我还想确保 UUT 不会调用任何其他可能导致数据库更改的方法。

在犀牛模拟中,我做了以下操作:

  1. 我从 db 对象做了一个严格模拟
  2. 我在 Arrange 中做了一个 .Expect 子句
  3. 我在 Assert 中调用了 VerifyAllExpectations

但是,当我想在 FakeItEasy 中执行此操作时,如果没有代码重复,我找不到如何执行此操作。我尝试将 CallsTo()+MustHaveHappened() 部分放在 Arrange 中,但是我的测试失败了。如果我将 CallsTo()+MustHaveHappened() 部分放在 Assert 中,那么我的测试也会失败,因为对严格的假货进行了意外调用。这可以在不将 CallsTo 调用同时放入 Arrange 和 Assert 的情况下完成吗?

【问题讨论】:

  • UUT = 被测单元?
  • 是的,UUT = 被测单元
  • 我明白了,谢谢。我以前没听过这个词。我通常使用 SUT - 被测系统。

标签: c# unit-testing rhino-mocks fakeiteasy


【解决方案1】:

虽然@jimmy_keen 的答案会起作用(我什至赞成),但 FakeItEasy 的更惯用用法是:

// Arrange
var service = A.Fake<IService>(o => o.Strict()); // only allows configured calls
A.CallTo(() => service.PostData("data")).DoesNothing(); // allow a specific call

// Act
testedObject.CallService("data");

// Assert
A.CallTo(() => service.PostData("data")).MustHaveHappened(Repeated.Exactly.Once);

--- 更新 ---

在@blairconrad https://github.com/FakeItEasy/FakeItEasy/issues/198#issuecomment-29145440 的帮助下,我认为这是做到这一点的最巧妙方法,无需重复:

// Arrange
var service = A.Fake<IService>(o => o.Strict()); // only allows configured calls
var expectedCall = A.CallTo(() => service.PostData("data"));
expectedCall.DoesNothing(); // allow the call

// Act
testedObject.CallService("data");

// Assert
expectedCall.MustHaveHappened(Repeated.Exactly.Once);

【讨论】:

  • "在不将 CallsTo 调用同时放入 Arrange 和 Assert 的情况下可以做到这一点吗?"我知道这个版本,我的问题就是要避免这种情况。
  • 您对代码重复有意见。目前没有办法通过严格的假而不重复代码来实现这一点。我已在 FakeItEasy 重新打开该问题以进一步讨论 github.com/FakeItEasy/FakeItEasy/issues/…
  • 哇,所以 CallTo 返回了一个“调用对象”,可以稍后验证。有趣,点赞。
  • 是的,它是 FakeItEasy。这很简单。 ;-)
【解决方案2】:

您可以通过以下验证来实现:

var service = A.Fake<IService>();

testedObject.CallService("data");

// verify your specific call to .PostData
A.CallTo(() => service.PostData("data")).MustHaveHappened(Repeated.Exactly.Once);
// verify that no more than 1 call was made to fake object
A.CallTo(service).MustHaveHappened(Repeated.Exactly.Once); 

A.CallTo(object) 重载允许您对所有和任何伪对象方法进行通用设置/验证。

【讨论】:

  • +1 这行得通。仅供参考,我已经对 FIE 所有者进行了民意调查,以了解是否有更优雅的方法来解决这个问题github.com/FakeItEasy/FakeItEasy/issues/198
  • 我回答@AdamRalph 说“为什么不把() =&gt; service.PostData…) 吸进一个变量并在Arrange 和Assert 中使用它?它仍然是两个调用,就像在这个答案中一样,但是(我认为) 稍微更惯用的 FIE。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多