beapp/repository-tester-bundle
Installation Add the bundle via Composer:
composer require beapp/repository-tester-bundle
Enable it in config/bundles.php:
return [
// ...
BeApp\RepositoryTesterBundle\BeAppRepositoryTesterBundle::class => ['all' => true],
];
First Use Case
Test a simple repository method (e.g., find()):
use BeApp\RepositoryTesterBundle\Test\RepositoryTestTrait;
use App\Repository\UserRepository;
class UserRepositoryTest extends \PHPUnit\Framework\TestCase
{
use RepositoryTestTrait;
public function testFindUser()
{
$this->createRepositoryTest(UserRepository::class)
->withEntityManager($this->createMockEntityManager())
->withEntity(User::class)
->assertFind(1, User::class, ['id' => 1]);
}
}
Key Classes
RepositoryTestTrait: Core trait for repository testing.MockEntityManager: Pre-configured mock for Doctrine’s EntityManager.RepositoryTester: Builder for repository test cases.Basic Assertions Test CRUD operations with minimal setup:
$this->createRepositoryTest(UserRepository::class)
->withEntityManager($this->createMockEntityManager())
->withEntity(User::class)
->assertFind(1, User::class, ['id' => 1])
->assertFindAll([$user1, $user2])
->assertSave($user1)
->assertDelete($user1);
Custom Query Testing Mock complex queries (e.g., DQL):
$this->createRepositoryTest(UserRepository::class)
->withEntityManager($this->createMockEntityManager())
->assertQueryResult(
'SELECT u FROM App\Entity\User u WHERE u.email = :email',
['email' => 'test@example.com'],
[$user]
);
Integration with Laravel
EntityManager via Laravel’s Doctrine\DBAL\Connection or EntityManager facade.createMockEntityManager() to inject Laravel’s EntityManager:
protected function createMockEntityManager(): EntityManager
{
return $this->getEntityManager(); // Laravel's EM
}
Data Fixtures Load fixtures before tests:
$this->createRepositoryTest(UserRepository::class)
->withFixtures([new UserFixture()])
->assertFind(1, User::class);
MockEntityManager to support Laravel’s query builder:
$mockEM = $this->createMockEntityManager();
$mockEM->expects($this->once())
->method('createQueryBuilder')
->willReturn(LaravelQueryBuilder::from('users'));
$this->beginTransaction();
$this->createRepositoryTest(...);
$this->rollBack();
EntityManager Mocking
EntityManager can break lazy-loading or event listeners.find(), persist()).Laravel Doctrine Quirks
EntityManager may not fully implement Symfony’s EntityManagerInterface.createMockEntityManager() with partial mocking:
$mockEM = $this->getMockBuilder(EntityManager::class)
->disableOriginalConstructor()
->onlyMethods(['find', 'persist'])
->getMock();
Fixture Loading
load() method.FixtureInterface and are autoloaded.Query Builder Assertions
$this->assertQueryMatches('/SELECT.*FROM App\Entity\User/', $query);
BEAPP_REPOSITORY_TESTER_DEBUG=true in .env to log query expectations.var_dump($mockEM->getMockMethods()) to check which methods are mocked.Custom Assertions
Extend RepositoryTestTrait to add domain-specific assertions:
protected function assertCustomLogic($repository, $input, $expected)
{
$result = $repository->customMethod($input);
$this->assertEquals($expected, $result);
}
Laravel Service Provider
Bind the bundle’s services to Laravel’s container in AppServiceProvider:
$this->app->bind(EntityManager::class, function () {
return $this->app->make('doctrine')->getManager();
});
PHPUnit Extensions Create a custom test listener to log repository test results:
class RepositoryTestListener implements TestListener
{
public function endTest(Test $test, $time): void
{
if (str_contains($test->getName(), 'RepositoryTest')) {
// Log custom metrics
}
}
}
How can I help you explore Laravel packages today?