Test Class

Another alternative is to use the Test Class pattern. The idea is to extend the Post class with a new one that we can manipulate to force specific scenarios. This new class is going to be used only for unit testing purposes. The bad news is that we have to modify the original Post class a bit, extracting some methods and changing some fields and methods from private to protected. Some developers may worry about increasing the visibility of class properties just because of testing reasons. However, we think that in most cases, it's worth it:

class Post
{
protected $createdAt;

public function isNew()
{
return
($this->today())
->diff($this->createdAt)
->days <= self::NEW_TIME_INTERVAL_DAYS;
}

protected function today()
{
return new DateTimeImmutable();
}

protected function createdAt(DateTimeImmutable $aDate)
{
$this->assertIsAValidDate($aDate);

$this->createdAt = $aDate;
}
}

As you can see, we've extracted the logic for getting today's date into the today() method. This way, by applying the Template Method pattern, we can change its behavior from a derived class. Something similar happens with the createdAt method and field. Now they're protected, so they can be used and overridden in derived classes:

class PostTestClass extends Post
{
private $today;

protected function today()
{
return $this->today;
}

public function setToday($today)
{
$this->today = $today;
}
}

With these changes, we can now test our original Post class through testing PostTestClass:

class PostTest extends PHPUnit_Framework_TestCase
{
// ...

/** @test */
public function aPostIsNewIfIts15DaysOrLess()
{
$aPost = new PostTestClass(
'A Post Content' ,
'A Post Title'
);

$format = 'Y-m-d';
$dateString = '2016-01-01';
$createdAt = DateTimeImmutable::createFromFormat(
$format,
$dateString
);

$aPost->createdAt($createdAt);
$aPost->setToday(
$createdAt->add(
new DateInterval('P15D')
)
);

$this->assertTrue(
$aPost->isNew()
);

$aPost->setToday(
$createdAt->add(
new DateInterval('P16D')
)
);

$this->assertFalse(
$aPost->isNew()
);
}
}

Just one last small detail: with this approach, it's impossible to achieve 100 percent coverage on the Post class, because the today() method is never going to be executed. However, it can be covered by other tests.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset