在同一对象中的另一个方法上使用FakeItEasy的A.CallTo()

本文关键字:FakeItEasy CallTo 方法 对象 另一个 | 更新日期: 2023-09-27 18:25:19

使用FakeItEasy,如何检查我对象的方法是否在同一对象上调用了另一个方法?

测试:

[TestMethod]
public void EatBanana_CallsWillEat()
{
  var banana = new Banana();
  var myMonkey = new Monkey();
  myMonkey.EatBanana(banana);
  //this throws an ArgumentException, because myMonkey is a real instance, not a fake
  A.CallTo(() => myMonkey.WillEat(banana)
    .MustHaveHappened();
}

班级:

public class MyMonkey {
  private readonly IMonkeyRepo _monkeyRepo;
  public MyMonkey(IMonkeyRepo monkeyRepo) {
    _monkeyRepo = monkeyRepo;
  }
  public void EatBanana(Banana banana) {
    //make sure the monkey will eat the banana
    if (!this.WillEat(banana)) {
      return;
    }
    //do things here
  }
  public bool WillEat(Banana banana) {
    return !banana.IsRotten;
  }
}

我愿意接受建议。 如果我做错了,请告诉我。

在同一对象中的另一个方法上使用FakeItEasy的A.CallTo()

你为什么要嘲笑被测试的对象?你到底想测试什么?呼叫WillEat发生的验证价值不大。它向消费者提供哪些信息?毕竟,消费者并不关心方法是如何实现的。消费者关心结果如何。

当猴子吃了没有腐烂的香蕉时会发生什么?您的测试应回答以下问题:

[TestMethod]
public void EatBanana_CAUSES_WHAT_WhenBananaIsNotRotten()
{
    var repo = A.Fake<IMonkeyRepo>();
    var monkey = new Monkey(repo);
    var freshBanana = new Banana { IsRotten = false };
    monkey.EatBanana(freshBanana);
    // verifications here depend on what you expect from
    // monkey eating fresh banana
}

请注意,您可以对IMonkeyRepo进行各种验证,此处已正确伪造并注入。

这是可以做到的。如果WillEat方法是虚拟的 - 否则FakeItEasy将无法伪造它。

通过该更改,您可以执行以下操作:

[TestMethod]
public void EatBanana_CallsWillEat()
{
    var fakeMonkey = A.Fake<MyMonkey>();
    fakeMonkey.EatBanana(new Banana());
    A.CallTo(()=>fakeMonkey.WillEat(A<Banana>._)).MustHaveHappened();
}

我仍然不相信这是一个好主意(正如我在评论中咆哮的那样( - 我认为你最好依靠其他可观察的行为,但我不熟悉你的系统。如果您认为这是最好的方法,则示例代码应该适合您。