PHP单元测试方法
请看下面的代码。我们有一个类FightService,它实现了两个英雄之间战斗的逻辑。战斗结束后,其中一位英雄可能会失去一些生命值 如何以正确的方式实现PHP单元测试方法,php,unit-testing,phpunit,Php,Unit Testing,Phpunit,请看下面的代码。我们有一个类FightService,它实现了两个英雄之间战斗的逻辑。战斗结束后,其中一位英雄可能会失去一些生命值 如何以正确的方式实现FightService::fight()方法的测试 如果您认为需要,可以随意重构任何代码 使用PHPUnit\Framework\TestCase; 接口接口 { 公共函数getAttack():int; 公共函数getDefense():int; 公共函数getHealthPoints():int; 公共功能设置健康点(int$healthP
FightService::fight()
方法的测试
如果您认为需要,可以随意重构任何代码
使用PHPUnit\Framework\TestCase;
接口接口
{
公共函数getAttack():int;
公共函数getDefense():int;
公共函数getHealthPoints():int;
公共功能设置健康点(int$healthPoints);
}
类损伤计算器
{
恒损系数=0.2;
公共静态函数CalculatedImage(英雄界面$攻击者,英雄界面$defender):int
{
$damage=0;
如果($attacker->getAttack()>$defender->getDefence()){
$baseDamage=$attacker->getAttack()-$defender->getDefence();
$factor=$baseDamage*self::损害系数;
$minDamage=$baseDamage-$factor;
$maxDamage=$baseDamage+$factor;
$damage=mt_rand($minDamage,$maxDamage);
}
退还$damage;
}
}
阶级斗争服务
{
公共功能战斗(英雄界面$攻击者,英雄界面$防御者)
{
$damage=DamageCalculator::calculateDamage($attacker,$defender);
$defender->setHealthPoints($defender->getHealthPoints()-$damage);
}
}
类FightServiceTest扩展了TestCase{
公共函数testFight()
{
//这里是我的测试,但不工作,我无法将参数传递到接口,所以我不确定我在做什么?
$playerOne=兰特(1100);
$playerTwo=兰特(1100);
$this->assertInstanceOf(
FightService::类,
战斗服务::战斗($playerOne,$playerTwo)
);
}
}
静态调用是固定的依赖项,应该避免。如果使用依赖项注入,则可以使用存根和/或模拟替换依赖项
因此,DamageCalculator也可以作为一个接口,并允许不同的实现
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);
}
}
无法将参数传递给接口。您需要创建一个
实现
此接口的类,并创建该类的对象以在测试中使用:类Hero实现HeroInterface(){public function getAttack():int{//add some code}public function getDefense():int{//add some code}public function getHealthPoints():int{//add some code}公共函数setHealthPoints(int$healthPoints){//add some code}如果您认为有必要,可以随意重构任何代码。
是的,您可以通过模拟接口来避免创建新类:。但我认为首先您应该进行一个测试,该测试可以正常工作,并用一个类回答问题,然后在删除该类后再尝试进一步。非常棒的thx duo,这个有趣的公共函数testF呢ight(HeroInterface$interface){//实现测试$rand=rand(1100);$interface->getAttack($rand);$interface->GetDefense($rand);$interface->getHealthPoints($rand);$this->assertInstanceOf(FightService::fight());}