Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

grandadevans's avatar

Help with Mockery not working

HI All,

I am trying to run a test but I cannot get Mockery to mock Carbon. I have simplified the class under test and the test itself and of course included phpunit's result. Any help would be greatly appreciated as I'm all out of ideas on this one.

Test (simplified)

use Mockery as m;

class MedicationTest extends TestCase
{
    public function tearDown()
    {
        m::close();
    }

    public function test_we_get_days_of_prescription_remaining()
    {
        m::mock('\Carbon\Carbon')->shouldReceive('addDays')->once();
        $med = new \MPC\Models\Medication();
        $med->getDaysOfPrescriptionRemaining();
    }
}

Class under test (simplified)

namespace MPC\Models;

use Illuminate\Database\Eloquent\Model;

class Medication extends Model
{
    public $timesTakenPerTimePeriod;
    public $howManyTakenPerTime;
    public $timePeriodTakenOver;
    public $unitsPerPrescription;
    public $datePrescriptionLastFilled;

    protected $table = 'medication';

    protected $fillable = [
        'user_id',
        'name',
        'RXCUI',
        'preferredName',
        'sizeOfEachUnit',
        'unitOfMeasurement',
        'howManyTakenPerTime',
        'timesTakenPerTimePeriod',
        'timePeriodTakenOver',
        'unitsPerPrescription',
        'datePrescriptionLastFilled',
        'reminder',
        'remarks'
    ];

    public function getDaysOfPrescriptionRemaining()
    {
        $carbon = new \Carbon\Carbon();
        return $carbon->addDays(25);
    }

}

Result

Runtime:        PHP 5.5.27
Configuration:  /Users/jev04/MPC/phpunit.xml


Starting test 'MedicationTest::test_we_get_days_of_prescription_remaining'.
E

Time: 158 ms, Memory: 13.00Mb

There was 1 error:

1) MedicationTest::test_we_get_days_of_prescription_remaining
Mockery\Exception\InvalidCountException: Method addDays() from Mockery_0__Carbon should be called
 exactly 1 times but called 0 times.

/Users/jev04/MPC/vendor/mockery/mockery/library/Mockery/CountValidator/Exact.php:37
/Users/jev04/MPC/vendor/mockery/mockery/library/Mockery/Expectation.php:271
/Users/jev04/MPC/vendor/mockery/mockery/library/Mockery/ExpectationDirector.php:120
/Users/jev04/MPC/vendor/mockery/mockery/library/Mockery/Container.php:297
/Users/jev04/MPC/vendor/mockery/mockery/library

Thanks for looking :-)

0 likes
3 replies
grandadevans's avatar
grandadevans
OP
Best Answer
Level 4

Managed to solve it. I wasn't passing in the mocked instance of carbon. So although I was passing in the correct class path it didn't work. I got the idea of checking from here http://stackoverflow.com/questions/27745950/mocked-class-not-accepting-instance-of-carbon

So my simplified code now looks like Test

use Carbon\Carbon;
use Mockery as m;

class MedicationTest extends TestCase
{
    public $carbon;

    public function setUp()
    {
        $this->carbon = m::mock(Carbon::class);
        $this->carbon->shouldReceive('addDays')->once();

    }
    public function test_we_get_days_of_prescription_remaining()
    {

        $med = new \MPC\Models\Medication();
        $med->getDaysOfPrescriptionRemaining($this->carbon);
    }
}

CUT

namespace MPC\Models;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;

class Medication extends Model
{
    public $timesTakenPerTimePeriod;
    public $howManyTakenPerTime;
    public $timePeriodTakenOver;
    public $unitsPerPrescription;
    public $datePrescriptionLastFilled;

    protected $table = 'medication';

    protected $fillable = [
        'user_id',
        'name',
        'RXCUI',
        'preferredName',
        'sizeOfEachUnit',
        'unitOfMeasurement',
        'howManyTakenPerTime',
        'timesTakenPerTimePeriod',
        'timePeriodTakenOver',
        'unitsPerPrescription',
        'datePrescriptionLastFilled',
        'reminder',
        'remarks'
    ];

    public function getCarbonDate()
    {
       return new \Carbon\Carbon();
    }
    public function getDaysOfPrescriptionRemaining(Carbon $carbon)
    {
        return $carbon->addDays(25);
    }

}

It obviously needs tidying up and the original (non-simplified) code putting back in there but that can wait until tomorrow. ps I am aware that I could use a $dates property and get a Carbon date by default but this way the test has more isolation.

ifpingram's avatar

When you say you simplified the test, did you mean you also pulled out all the assertions, as I cannot see any there in your test?

sachem's avatar

shouldReceive is an assertion and it's still there ;)

1 like

Please or to participate in this conversation.