Skip to content
Advertisement

Carbon object in mockery php test

Thank you for your time. I have stripped out the fluff from the code/test.

The furthest I have got with this is that setAttribute requires two strings as param´s, but i am passing in an Carbon object, which Mockery as a test suite does not like? Is this the case, is there a better way to test dates with Mockery/PHPUnit? Other tests and code works, it seems like it´s only this test that is an issue.

Error

1) TestsUnitServicesStageServiceTest::update_stage
MockeryExceptionNoMatchingExpectationException: No matching handler found for Mockery_13_App_Entities_Subcategory::setAttribute('stage_updated_at', object(CarbonCarbon)). Either the method was unexpected or its arguments matched no expected argument list for this method

Objects: ( array (
  'Carbon\Carbon' => 
  array (
    'class' => 'Carbon\Carbon',
    'properties' => 
    array (
    ),
  ),
))

Bit of the test

        $subcategory = Mockery::mock(Subcategory::class);
        $stage = Mockery::mock(Stage::class);
        $subcategory
            ->shouldReceive('setAttribute')
            ->with('stage_updated_at', Carbon::now())
            ->once();
       $this->service->updateSubcategoryStage(self::SUBCATEGORY_ID, $stageId);

Bit of the code

        $subcategory->stage_updated_at = Carbon::now();
        $subcategory->save();

Advertisement

Answer

It’s not clear from your example who’s calling setAttribute. But I guess that you are probably using magic setters.

The reason why your expectation is failing is because you are comparing two different objects. From the docs:

When matching objects as arguments, Mockery only does the strict === comparison, which means only the same $object will match

You can loosen the comparison by using the equalTo hamcrest matcher:

$subcategory
    ->shouldReceive('setAttribute')
    ->with('stage_updated_at', equalTo(Carbon::now()))
    ->once();

You will still get into trouble because the time will always be slightly off. Fortunately, Carbon provides a way to fix “now” for testing purposes. You just have to set it in your test case:

Carbon::setTestNow('2020-01-31 12:13:14');
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement