如何模拟碳方法链

时间:2014-04-22 17:42:01

标签: laravel-4 tdd mockery php-carbon

我正在试图模仿Carbon::parse($date)->format("Y"),但我不确定该怎么做。

这是我到目前为止所做的:

public function testGetYear2014FromPost()
{
    $mock = Mockery::mock("DateFormatter");
    $mock->shouldReceive("parse")
        ->with("2014-02-08 16:23:33")
        ->once()
        ->andReturn($mock);
    $mock->shouldReceive("format")
        ->with("Y")
        ->once()
        ->andReturn("2014");

    $this->article->setDateFormatter($mock);

    $this->assertEquals("2014", $this->article->getYear());
}

1 个答案:

答案 0 :(得分:2)

我只知道两种模拟方法链的方法:

  1. 计算每种方法的返回值&嘲笑:
  2. 
    $mock1 = Mockery::mock("SomeOtherClass")
    $mock1->shouldReceive("format")->with("Y")->once()->andReturn("2014");
    
    $mock0 = Mockery::mock("DateFormatter")
    $mock0->shouldReceive("parse")
        ->with("2014-02-08 16:23:33")->once()->andReturn($mock1);
    

    你必须找出parse方法返回的类,然后将其设置为模拟对象&把它归还。

    1. 如果您不想弄清楚返回的类是什么,可以使用stdClass对象来捏造它:
    2. 
      $mock1 = new stdClass;
      $mock1->format = function ($f) { return "2014"; };
      
      $mock0 = Mockery::mock("DateFormatter")
      $mock0->shouldReceive("parse")
          ->with("2014-02-08 16:23:33")->once()->andReturn($mock1);
      

      这两种方法之间存在重要差异:

      • 第一种方法是更多的工作,但它允许你为Mockery设置准确的期望,这将允许PHPUnit&如果不满足期望,就可以妥善处理事情。

      • 第二个更容易,但是你没有得到期望处理。但是,有可能通过在未满足您的预期时抛出异常来捏造,例如:

      $mock1 = new stdClass;
      $mock1->format = function ($f) {
          if ($f!="Y") {
              throw new Exception;
          }
          return "2014";
      };
      
      $mock0 = Mockery::mock("DateFormatter")
      $mock0->shouldReceive("parse")
          ->with("2014-02-08 16:23:33")->once()->andReturn($mock1);
      

      然后,您可以在方法中添加@expectedException Exception docblock来测试它。