Faking Carbon test dates

Carbon is one of the main datetime libraries used during Laravel development, and it provides many friendly functions for datetime manipulation and mathematics.  But what if you want to test code which calls functions such as today() or now()?

It is very common to find business logic which uses functions such as today() to evaluate program flow. e.g. to update persistent storage only if it is a weekday, or to schedule tasks for a week hence. While it may be possible to write some unit test which execute successfully using the real datetime, there are many occasions where we need to fake the date in order to be certain of our expected results. Fortunately, Carbon has this covered.

// Setup - Carbon will return 12:00 on 25/12/2019 as now()
$testDate = Carbon::create(2019, 12 25, 12);
Carbon::setTestNow($testDate);

// execute business logic
$businessClass->process();

// test assertion
$this->assertEquals(
   // test the date manipulation
);

// Clean Up
Carbon::setTestNow();

Note that if you don’t clean up properly then you could unwittingly invalidate other tests that rely upon Carbon.