3

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

在犀牛模拟中,我做了以下事情:

  1. 我从 db 对象做了一个 strictmock
  2. 我在安排中做了一个 .Expect 子句
  3. 我在 Assert 中调用了 VerifyAllExpectations

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

4

2 回答 2

6

虽然@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);

- - 更新 - -

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

// 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);
于 2013-11-21T22:10:27.017 回答
5

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

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)进行通用设置/验证。

于 2013-11-20T14:19:54.437 回答