Hầu hết thời gian, kiểm tra cơ sở dữ liệu trong bộ nhớ đơn giản hơn so với chế độ chế nhạo. Nó cũng linh hoạt hơn rất nhiều. Và nó cũng kiểm tra các tệp di chuyển được thực hiện tốt (khi có các tệp di chuyển).
Xem mã giả này:
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');
}
}
Việc InMemoryTest
này không phụ thuộc vào cách Database
triển khai vào UserRepository
công việc. Nó chỉ đơn giản là sử dụng UserRepository
giao diện công cộng ( create
) và sau đó khẳng định chống lại nó. Thử nghiệm đó sẽ không bị hỏng nếu bạn thay đổi triển khai nhưng chậm hơn.
Trong khi đó, các MockingDBTest
phụ thuộc đầy đủ vào cách Database
thực hiện vào UserRepository
. Trong thực tế, nếu bạn thay đổi việc thực hiện nhưng vẫn khiến nó hoạt động theo cách khác, thử nghiệm đó sẽ bị hỏng.
Tốt nhất của cả hai thế giới sẽ sử dụng giao diện giả thực hiện Database
giao diện:
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;
}
}
Đó là cách biểu cảm hơn, dễ đọc và dễ hiểu hơn và nó không phụ thuộc vào việc triển khai Cơ sở dữ liệu thực tế được thực hiện ở các lớp mã cao hơn.