La mayoría de las veces, las pruebas de bases de datos en memoria son más simples que las burlas. También es mucho más flexible. Y también prueba que los archivos de migración estén bien (cuando hay archivos de migración).
Vea este pseudocódigo:
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');
}
}
El InMemoryTestno depende de cómo Databasese implementa en el UserRepositorytrabajo. Simplemente usa la UserRepositoryinterfaz pública ( create) y luego afirma contra ella. Esa prueba no se romperá si cambia la implementación, pero es más lenta.
Mientras tanto, MockingDBTestdepende totalmente de cómo Databasese implementa UserRepository. De hecho, si cambia la implementación pero aún así hace que funcione de otra manera, esa prueba se rompería.
Lo mejor de ambos mundos sería usar una falsa implementación de la Databaseinterfaz:
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;
}
}
Eso es mucho más expresivo, más fácil de leer y entender, y no depende de la implementación de la base de datos real realizada en las capas superiores del código.