Sebagian besar waktu, pengujian basis data dalam memori lebih sederhana daripada mengejek. Ini juga jauh lebih fleksibel. Dan itu juga menguji file migrasi dilakukan dengan baik (ketika ada file migrasi).
Lihat kode semu ini:
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');
}
}
Tidak InMemoryTest
tergantung pada bagaimana Database
diterapkan ke dalam UserRepository
pekerjaan. Itu hanya menggunakan UserRepository
antarmuka publik ( create
) dan kemudian menegaskan menentangnya. Tes itu tidak akan rusak jika Anda mengubah implementasi tetapi lebih lambat.
Sementara itu, MockingDBTest
sepenuhnya bergantung pada bagaimanaDatabase
diimplementasikan ke dalam UserRepository
. Bahkan, jika Anda mengubah implementasi tetapi masih membuatnya bekerja dengan cara lain, tes itu akan pecah.
Terbaik dari kedua dunia akan menggunakan palsu yang mengimplementasikan Database
antarmuka:
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;
}
}
Itu jauh lebih ekspresif, lebih mudah dibaca dan dimengerti, dan itu tidak tergantung pada implementasi dari Database aktual yang dilakukan pada lapisan kode yang lebih tinggi.