Il più delle volte, il test del database in memoria è più semplice del deridere. È anche molto più flessibile. Inoltre, verifica che i file di migrazione siano eseguiti correttamente (quando sono presenti file di migrazione).
Vedi questo pseudo codice:
class InMemoryTest
{
/** @test */
public function user_repository_can_create_a_user()
{
$this->flushDatabase();
$userRepository = new UserRepository(new Database());
$userRepository->create('name', 'email@email.com');
$this->seeInDatabase('users', ['name' => 'name', 'email' => 'email@email.com']);
}
}
class MockingDBTest
{
/** @test */
public function user_repository_can_create_a_user()
{
$databaseMock = MockLib::mock(Database::class);
$databaseMock->shouldReceive('save')
->once()
->withArgs(['users', ['name' => 'name', 'email' => 'email@email.com']]);
$userRepository = new UserRepository($databaseMock);
$userRepository->create('name', 'email@email.com');
}
}
Il InMemoryTest
non dipende da come Database
viene implementato in UserRepository
al lavoro. Usa semplicemente l' UserRepository
interfaccia pubblica ( create
) e quindi afferma contro di essa. Quel test non si interromperà se cambi l'implementazione ma è più lento.
Nel frattempo, MockingDBTest
tutto dipende da come Database
viene implementato UserRepository
. In effetti, se si modifica l'implementazione ma si fa ancora funzionare in un altro modo, tale test si interromperà.
Il meglio di entrambi i mondi sarebbe usare un falso implementando l' Database
interfaccia:
class UsingAFakeDatabaseTest
{
/** @test */
public function user_repository_can_create_a_user()
{
$fakeDatabase = new FakeDatabase();
$userRepository = new UserRepository($fakeDatabase);
$userRepository->create('name', 'email@email.com');
$this->assertEquals('name', $fakeDatabase->datas['users']['name']);
$this->assertEquals('email@email.com', $fakeDatabase->datas['users']['email']);
}
}
interface DatabaseInterface
{
public function save(string $table, array $datas);
}
class FakeDatabase implements DatabaseInterface
{
public $datas;
public function save(string $table, array $datas)
{
$this->datas[$table][] = $datas;
}
}
Questo è molto più espressivo, più facile da leggere e da capire e non dipende dall'implementazione del database effettivo fatto nei livelli più alti del codice.