I have recently encountered multiple articles with title Everytime a mock returns a mock a fairy dies And I ran into exact same situation while using factory class in my code. I am writing a sample Java code here to explain in detail what I mean.
@RequiredArgsConstructor
class Battle{
private final GunFactory;
public Damage attack(Bullet availableBullet, Enemy enemy){
Gun gun = gunFactory.create(availableBullet);
return gun.shoot(enemy);
}
}
class BattleTest{
private GunFactory gunFactory = mock(GunFactory.class);
private Gun gun = mock(Gun.class);
private Battle battle = new Battle(gunFactory);
@Test
public void attack(){
Enemy anyEnemy = new Enemy(strength=10);
Bullet anyBullet = new Bullet("Machine gun bullet");
Damage anyDamage = new Damage(100);
when(gunFactory.create(anyAvailableBullet)).thenReturn(gun);
when(gun.shoot(anyEnemy)).thenReturn(anyDamage);
assertThat(battle.attack(anyBullte, anyEnemy), is(anyDamage));
}
}
As you can see in the sample (ugly) code my factory is a mock and is returning another mock. So it got me wondering if there is anyway to avoid this. I tried moving one class higher, so that the GunFactory
sends Gun
object as a parameter to attack
function, but I would still run into same issue when I test the other class.
Is there a way to avoid this. Or with factory pattern is this inevitable?
Battle.attack
, when it should really relate the expectedDamage
result from theBullet
andEnemy
arguments.