대부분의 경우 메모리 내 데이터베이스 테스트는 조롱보다 간단합니다. 또한 훨씬 유연합니다. 또한 마이그레이션 파일이있는 경우 마이그레이션 파일이 제대로 수행되는지 테스트합니다.
이 의사 코드를 참조하십시오 :
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;
}
}
이는보다 표현적이고 읽기 쉽고 이해하기 쉬운 방법이며 더 높은 코드 계층에서 수행되는 실제 데이터베이스의 구현에 의존하지 않습니다.