Static calls are fixed dependencies and should be avoided. If you use dependency injection you can replace the dependencies with stubs and/or mocks.
With that the DamageCalculator can be an interface as well and allow for different implementations.
use PHPUnit\Framework\TestCase;
interface HeroInterface {
public function getAttack(): int;
public function getDefence(): int;
public function getHealthPoints(): int;
public function setHealthPoints(int $healthPoints);
}
interface DamageCalculatorInterface {
public function calculateDamage(HeroInterface $attacker, HeroInterface $defender): int;
}
class FightService {
/**
* @var DamageCalculatorInterface
*/
private $_damageCalculator;
public function __construct(DamageCalculatorInterface $damageCalculator) {
$this->_damageCalculator = $damageCalculator;
}
public function fight(HeroInterface $attacker, HeroInterface $defender) {
$damage = $this->_damageCalculator->calculateDamage($attacker, $defender);
$defender->setHealthPoints($defender->getHealthPoints() - $damage);
}
}
class FightServiceTest extends TestCase {
public function testFight(): void {
$attacker = $this->createMock(HeroInterface::class);
$defender = $this->createMock(HeroInterface::class);
$defender
->expects($this->once())
->method('getHealthPoints')
->willReturn(21);
$defender
->expects($this->once())
->method('setHealthPoints')
->with(16);
$damageCalculator = $this->createMock(DamageCalculatorInterface::class);
$damageCalculator
->expects($this->once())
->method('calculateDamage')
->with($attacker, $defender)
->willReturn(5);
$fightService = new FightService($damageCalculator);
$fightService->fight($attacker, $defender);
}
}
solved PHP UNIT TEST METHODS