Presented by Guyllaume Cardinal for Cogeco Connexion
TDD vs BDD
Benefits of TDD
Coding principles: SOLID, GRASP Single Responsability principle
Code smells
Tests a single unit (class)
Focus on behavior
Mocks are used to isolate what is being tested
We have tests for each classes, but we need to make sure they properly interact together.
Mocks can only go so far
(without becoming unmanageable)
You need to confirm proper behavior
There will be some overlap with your unit tests, but very few
We test for a feature's proper integration
(I feel no shame doing this pun)
<?php
/** A million imports **/
class FizBuzzTest extends TestCase {
/**
* @test
*/
public function it_should_print_an_array() {
$fizzBuzzArrayPrinter = new FizBuzzArrayPrinter(new FizBuzz());
$result = $fizzBuzzArrayPrinter->print(15, 1);
$this->assertTrue(is_array($result));
$this->assertContains(11, $result);
$this->assertContains('fiz', $result);
$this->assertContains('buzz', $result);
$this->assertContains('fizbuzz', $result);
}
}
Database and Web Services become an issue!
Interaction with these is slow and very unreliable
It's also a sign of binding in your code
It should already be in place! Abstractions to the rescue:
<?php
class EntityRepository
{
/**
* @var DatabaseManager
*/
protected $dbManager;
public function __construct(DatabaseManager $dbManager) {
$this->dbManager = $dbManager;
$this->dbManager->queryBuilder()->get('');
// And whatever stuff
}
}
You're now using an abstraction rather than interacting directly with your database or web service.
Suddenly you're able to inject test versions of these dependencies instead of the real ones.
Almost like a mock, but you're using real code and real data.
You can now have a DatabaseManager and TestDatabaseManager who both connect to something different.
<?php
namespace spec\Integration;
class FizBuzzTest extends TestCase {
/**
* @test
*/
public function it_should_use_an_abstraction() {
$databaseManager = new TestDatabaseManager(
new SQLiteDatabaseAdapter(),
'localhost:10000',
'user',
'password'
);
$repository = new EntityRepository($databaseManager);
/** And we test! */
}
}