php logo

Unit Testing Dates and Times with Carbon

One area of my codebase at work that I had problems sufficiently testing were instances in my code base that had time based logic to them. Since I work in the manufacturing sector, lots of logic relies on knowing what the current, last, or next shift is. There are lots of edge cases that need tested around shift change, especially third shift, which starts before midnight, but for all the reporting and other facets of my software it is technically tomorrow.

So these time-dependant functions for the most part did not have useful, functional unit tests, until recently. In the past I would write my logic, cross my fingers and wait for the bug reports to come rolling in. I'm so thankful that I discovered this testing aid built in to the Carbon PHP library. (If you haven't used Carbon, stop reading and go check it out, I'll forgive you. It makes working with dates and times in PHP a walk in the park, it is one of the most useful libraries I use!)

So now you are wondering, "What is this wonderful function that will let me test my date/time based logic easier?" I'm glad you asked. It is the setTestNow() function built in to the Carbon api. Basically, this allows you to determine when now() is.

// instantiate a carbon object equal to '2019-01-06 23:15:00)
$testDate = Carbon::create(2019, 1, 6, 23, 15);
Carbon::setTestNow($testDate);

$date = new Carbon();
// $date = '2019-01-06 23:15:00'

The great thing is that this now() persists across other classes, allowing easy time-based unit testing.

<?php

namespace Tests;

use App\Shift;
use Carbon\Carbon;
use PHPUnit\Framework\TestCase;

class ShiftTimesTest extends TestCase
{
    public function testThirdShift()
    {
        $testDate = Carbon::create(2019, 3, 8, 23, 15);
        Carbon::setTestNow($testDate);
        $shift = new Shift();

        $this->assertEquals(3, $shift->getCurrent());
    }
}

Discovering this helper has allowed me to add tests to lots of previously untested areas of the code base, and allowed me to get away from PDD (Prayer Driven Development).

If you liked this post, you can subscribe to the rss feed or follow me @ToddEidson on Twitter to be notified of future blog posts.

Date Published: 9 March, 2019

Tags: php

About Todd

Full stack application developer. Life-long learner. Pragmatic programmer. Believer in clean coding. Proponent for extensible and reusable code. Hobbies include (very) amateur photography, collecting old jazz records and going to live music performances.

North Central Ohio, US
toddeidson[dot]info

Obligatory Disclaimer

All opinions are my own, probably wrong, and subject to change without notice.

© 2017-2019 Todd Eidson. All content is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License.

Hosted on linode