Laravel 嘲讽:用 return 逻辑模拟

Laravel Mockery: mock with return logic

我想模拟(或存根?)一个 class 方法,它将 return 一个骰子结果。我希望模拟 return 一个预期值,比方说 2。但有时我也希望我的模拟 return 6;例如在 3:rd 骰子角色之后。

澄清一下,这是一个例子。用户决定角色 4 个骰子,我希望模拟始终为每个角色 return 2 - 除了 3:rd 一个应该 return a 6.

代码

我正在使用 PHP Laravel,我希望使用 Mockery 库。这就是我已经走了多远。对于此示例,我的代码有所简化。我仍然没有弄清楚如何根据方法参数使模拟给出不同的 returning 值。知道怎么做吗?

class DiceHelper{
    protected $diceClass;
    __construct($diceClass) // I set property diceClass in constructor...

   public function roleDices($nr_of_throws){
      for($x=0; $x < count($nr_of_throws); $x++) {
         $result = $diceClass->roleOneDice($x);
       }
   }
}

class diceClass
{
   public function roleOneDice($dice_order){
      return rand(1, 6);
   }
}

测试文件

class diceLogicTest extends TestCase
{
    /** @test */
    public function role_a_dice(){
        $mock = \Mockery::mock('diceClass[roleOneDice]');
        $mock->shouldReceive("roleOneDice")->andReturn(2);

        $theHelper = new DiceHelper($mock);
        $result = $theHelper->roleDices(2);

        $this->assertEquals(4,$result ); // Returns the expected 4.
    }
}

改进 如果有一种方法可以让 mock 在 returning 一个值之前计算它被调用的次数,那就太好了。这样我的 DiceHelper 方法 RoleDices 就不必发送参数 $x(当前掷骰子顺序)。我想不应该构建该方法来使测试工作。

这个 PHPUnit 解决方案非常完美。

$mock= $this->getMock('\diceClass');
$mock->method('roleOneDice')->will( $this->onConsecutiveCalls(2,2,3));

$theHelper = new DiceHelper($mock);
$result = $theHelper->roleDices(3);
$this->assertEquals(7, $result);

通过使用 onConsecutiveCalls,它将 return 每次调用模拟时的预期值。第一个 return 2,第三个 3。如果你调用 mock 超过 3 次,你需要更多的数字 - 我认为。