I'm trying to mock Carbon::parse($date)->format("Y") but I'm not sure how to go about it.

This is what I have so far:

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());
}
有帮助吗?

解决方案

I know of only two ways of mocking a method chain like that:

  1. figuring out the return value for each method & mocking that:

$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);

You have to figure out what class is returned by the parse method, then set that up as a mocked object & return it.

  1. If you don't want to go to the trouble of figuring out what the returned class is, you can fudge it with a stdClass object:

$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);

There's an important difference between these two approaches:

  • the first approach is a little more work, but it allows you to set up accurate expectations for Mockery which will allow PHPUnit & Mockery to properly handle things when the expectations are not met.

  • the second is a little easier, but you don't get the expectation handling. However, it is possible to fudge that by throwing an exception when your expecation is not met, like so:

$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);

You can then add an @expectedException Exception docblock to your method to test this.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top