使用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;
}
}
我愿意接受建议。如果我发现这一切都错了,请告诉我。
答案 0 :(得分:3)
你为什么嘲笑测试对象?你想要测试什么完全?调用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
进行所有类型的验证,这些验证都是正确伪造并在此处注入的。
答案 1 :(得分:2)
可以这样做。 如果 WillEat
方法是虚拟的 - 否则FakeItEasy将无法伪造它。
有了这个改变,你可以这样做:
[TestMethod]
public void EatBanana_CallsWillEat()
{
var fakeMonkey = A.Fake<MyMonkey>();
fakeMonkey.EatBanana(new Banana());
A.CallTo(()=>fakeMonkey.WillEat(A<Banana>._)).MustHaveHappened();
}
我仍然不相信这是一个好主意(因为我在评论中大肆宣传) - 我认为你最好依赖于其他可观察的行为,但我不熟悉你的系统。如果您认为这是最好的方法,示例代码应该适合您。