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 InMemoryTesttergantung pada bagaimana Databasediterapkan ke dalam UserRepositorypekerjaan. Itu hanya menggunakan UserRepositoryantarmuka publik ( create) dan kemudian menegaskan menentangnya. Tes itu tidak akan rusak jika Anda mengubah implementasi tetapi lebih lambat.
Sementara itu, MockingDBTestsepenuhnya 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 Databaseantarmuka:
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.