It can be a bit tricky when it comes to testing methods where DateTime object is used. This example shows us how to test such methods.


Class


declare(strict_types=1);

namespace Api\ExamBundle\Helper;

class ExamDate
{
public function getLastExamDay()
{
$date = $this->getDate('last day of this month');

if ($date == $this->getDate()) {
$date = $this->getDate('last day of next month');
}

if ($date->format('l') === 'Saturday') {
$date->modify('-1 day');
} elseif ($date->format('l') === 'Sunday') {
$date->modify('-2 days');
}

return $date->format('Y-m-d');
}

protected function getDate(?string $time = null): DateTime
{
return new DateTime($time);
}
}

Test


declare(strict_types=1);

namespace tests\Api\ExamBundle\Helper;

use Api\ExamBundle\Helper;
use DateTime;
use PHPUnit_Framework_MockObject_MockObject;
use PHPUnit_Framework_TestCase;

class ExamDateTest extends PHPUnit_Framework_TestCase
{
/**
* @test
*
* @dataProvider getLastExamDayProvider
*/
public function it_returns_last_exam_day($lastDayOfThisMonth, $today, $lastDayOfNextMonth, $expectedDay)
{
/** @var Adaptor|PHPUnit_Framework_MockObject_MockObject $mock */
$mock = $this->getMockBuilder(ExamDate::class)
->disableOriginalConstructor()
->setMethods(['getDate'])
->getMock();

$mock
->expects($this->at(0))
->method('getDate')
->willReturn(new DateTime($lastDayOfThisMonth));

$mock
->expects($this->at(1))
->method('getDate')
->willReturn(new DateTime($today));

if ($lastDayOfNextMonth) {
$mock
->expects($this->at(2))
->method('getDate')
->willReturn(new DateTime($lastDayOfNextMonth));
}

$this->assertEquals($expectedDay, $mock->getLastExamDay());
}

/**
* 1)
* Last day of this month : 2015-07-31 (Friday)
* Today : 2015-07-31 (Friday)
* Last day of this month : 2015-08-31 (Monday) *
* Result : 2015-08-31 (Monday) same day of *
*
* 2)
* Last day of this month : 2015-09-30 (Wednesday)
* Today : 2015-09-30 (Wednesday)
* Last day of this month : 2015-10-31 (Saturday) *
* Result : 2015-10-30 (Friday) -1 day of *
*
* 3)
* Last day of this month : 2015-04-30 (Thursday)
* Today : 2015-04-30 (Thursday)
* Last day of this month : 2015-05-31 (Sunday) *
* Result : 2015-15-29 (Friday) -2 days of *
*
* 4)
* Last day of this month : 2015-07-31 (Friday) *
* Today : 2015-07-30 (Thursday)
* Last day of this month :
* Result : 2015-07-31 (Friday) same day of *
*
* 5)
* Last day of this month : 2015-10-31 (Saturday) *
* Today : 2015-10-16 (Friday)
* Last day of this month :
* Result : 2015-10-30 (Friday) -1 day of *
*
* 6)
* Last day of this month : 2015-05-31 (Sunday) *
* Today : 2015-05-15 (Friday)
* Last day of this month :
* Result : 2015-05-29 (Friday) -2 days of *
*/
public function getLastExamDayProvider(): array
{
return [
['2015-07-31', '2015-07-31', '2015-08-31', '2015-08-31'],
['2015-09-30', '2015-09-30', '2015-10-31', '2015-10-30'],
['2015-04-30', '2015-04-30', '2015-05-31', '2015-05-29'],
['2015-07-31', '2015-07-30', null, '2015-07-31'],
['2015-10-31', '2015-10-16', null, '2015-10-30'],
['2015-05-31', '2015-05-15', null, '2015-05-29'],
];
}
}