Using FakeItEasy, how do I check to see if my object's method calls another method on this same object?
The Test:
[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();
}
The Class:
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;
}
}
I'm open to suggestions. If I'm going about this all wrong, please let me know.
Why are you mocking tested object? What exactly are you trying to test? The verification that call to WillEat
happened is of little value. What information does it server to consumer? After all, consumer doesn't care how method is implemented. Consumer cares what are the results.
What happens when monkey eats banana that is not rotten? Your test should answer this question:
[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
}
Note that you can make all sort of verifications to IMonkeyRepo
, which is properly faked and injected here.
It's possible to do this. If the WillEat
method were virtual - otherwise FakeItEasy won't be able to fake it out.
With that change, you could do this:
[TestMethod]
public void EatBanana_CallsWillEat()
{
var fakeMonkey = A.Fake<MyMonkey>();
fakeMonkey.EatBanana(new Banana());
A.CallTo(()=>fakeMonkey.WillEat(A<Banana>._)).MustHaveHappened();
}
I'm still not convinced it's a good idea (as I ranted in the comments) - I think you'd be better off relying on other observable behaviour, but I'm not familiar with your system. If you think this is the best way to go, the example code should work for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With