我正在学习 OOP 和干净的编码实践,为了做到这一点,我开始在 Laravel 中构建一个基于网络浏览器的游戏。
我有下面的类,它为我提供了一个随机数来知道一个动作是否成功:
class GenericDice
{
/**
*
* @param int $min
* @param int $max
* @return int
*/
public function random(int $min = 1, int $max = 100) : int
{
return mt_rand($min, $max);
}
}
现在在我的测试中,我想检查当 GenericDice::random()
返回 100 时,这意味着我必须将操作视为严重失败。
我阅读了 Laravel Mocking 文档、Mockery 文档 (它告诉我不要模拟静态方法,所以我改变了我使用 GenericDice
类的方式)并尝试了许多不同的方式这样做,但我不能告诉我的骰子给我一个固定的结果。
测试如下:
public function test_character_should_lose_health_when_action_is_critical_failure()
{
$this->mock(GenericDice::class, function (MockInterface $mock) {
$mock->shouldReceive("random")
->andReturn(100);
});
$character = Character::factory()->create([
"current_health" => 50,
]);
$response = $this->actingAs($character->user)->put(route("game.action.run"), [
"ordre_id" => $this->cookAction->id,
]);
$character->refresh();
$this->assertLessThan(50, $character->current_health);
}
运行动作的代码如下:
class CookAction extends AbstractAction
{
public function run(): bool
{
// Let's roll baby...
$this->diceResult = $this->throwDice();
// How did I do?
$this->checkForSuccess();
// The cooking part below.
}
}
// Below the AbstractAction
abstract class AbstractAction
{
protected function throwDice(int $min = 1, int $max = 100): int
{
return (new GenericDice)->random($min, $max);
}
}
我做错了什么?
答案 0 :(得分:1)
看起来您正在正确创建模拟,但您没有将模拟绑定到服务容器。您正在手动创建一个新的 GenericDice
,而不是让服务容器解析它。创建模拟并将其绑定到您的服务容器,然后让应用为您解析实例 GenericeDice
实例。
试试这个
public function test_character_should_lose_health_when_action_is_critical_failure()
{
$diceMock = \Mockery::mock(GenericDice::class)->makePartial();
$diceMock->shouldReceive('random')->andReturn(100);
// Bind to service container
$this->app->bind(
GenericDice::class,
function () use ($diceMock) {
return $diceMock;
}
);
$character = Character::factory()->create([
"current_health" => 50,
]);
$response = $this->actingAs($character->user)->put(route("game.action.run"), [
"ordre_id" => $this->cookAction->id,
]);
$character->refresh();
$this->assertLessThan(50, $character->current_health);
}
还有这个
abstract class AbstractAction
{
protected function throwDice(int $min = 1, int $max = 100): int
{
// Get the GenericeDice instance from the service container
$dice = app(GenericDice::class);
return $dice->random($min, $max);
}
}