Здебільшого тестування баз даних у пам'яті простіше, ніж глузування. Це також набагато гнучкіше. А також тестує, що файли міграції зроблені добре (коли є файли міграції).
Дивіться цей псевдо-код:
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');
}
}
InMemoryTest
Чи не залежить від того, як Database
реалізується в UserRepository
до роботи. Він просто використовує UserRepository
публічний інтерфейс ( create
), а потім стверджує проти нього. Цей тест не зламається, якщо ви зміните реалізацію, але це повільніше.
Тим часом, MockingDBTest
повністю покладається на те, як Database
реалізується UserRepository
. Насправді, якщо змінити реалізацію, але все-таки змусити її працювати іншим способом, цей тест порушиться.
Кращим з обох світів було б використання фальшивої реалізації Database
інтерфейсу:
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;
}
}
Таким чином виразніше, простіше читати та розуміти, і це не залежить від реалізації фактичної бази даних, зробленої у вищих шарах коду.