Laravel Mockery:模拟返回逻辑

Posted

技术标签:

【中文标题】Laravel Mockery:模拟返回逻辑【英文标题】:Laravel Mockery: mock with return logic 【发布时间】:2017-04-25 06:03:42 【问题描述】:

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

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

代码

我正在使用 php Laravel,我希望使用 Mockery 库。这就是我已经走了多远。对于这个例子,我的代码有些简化。我还没有弄清楚如何根据方法参数使模拟给出不同的返回值。知道该怎么做吗?

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.
    

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

【问题讨论】:

【参考方案1】:

这个 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 将在每次调用模拟时返回一个预期值。第一个它将返回 2,第三个将返回 3。如果你调用 mock 超过 3 次,你需要更多的数字 - 我认为。

【讨论】:

以上是关于Laravel Mockery:模拟返回逻辑的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5 - 使用 Mockery 模拟 Eloquent 模型

这个模拟对象上不存在方法 - Laravel,Mockery

使用 Mockery Eloquent 模型模拟 Laravel

用 Mockery 模拟 Laravel Model::increment()

在 Laravel(流明)上使用 Mockery 模拟 Eloquent 模型不起作用

Laravel + Mockery InvalidCountException