【问题标题】:Laravel Mockery: mock with return logicLaravel Mockery:模拟返回逻辑
【发布时间】: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 (当前的骰子投掷顺序)。我猜这个方法不应该是为了让测试工作而构建的。

【问题讨论】:

    标签: php laravel unit-testing mocking mockery


    【解决方案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 次,你需要更多的数字 - 我认为。

    【讨论】:

      猜你喜欢
      • 2014-01-09
      • 2015-03-27
      • 2014-11-05
      • 2013-11-04
      • 2016-08-17
      • 2022-01-04
      • 2016-09-11
      • 2016-01-14
      • 2022-10-04
      相关资源
      最近更新 更多