Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Repository Tester Bundle Laravel Package

beapp/repository-tester-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. 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],
    ];
    
  2. 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]);
        }
    }
    
  3. Key Classes

    • RepositoryTestTrait: Core trait for repository testing.
    • MockEntityManager: Pre-configured mock for Doctrine’s EntityManager.
    • RepositoryTester: Builder for repository test cases.

Implementation Patterns

Workflows

  1. 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);
    
  2. 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]
         );
    
  3. Integration with Laravel

    • Use Symfony’s EntityManager via Laravel’s Doctrine\DBAL\Connection or EntityManager facade.
    • Override createMockEntityManager() to inject Laravel’s EntityManager:
      protected function createMockEntityManager(): EntityManager
      {
          return $this->getEntityManager(); // Laravel's EM
      }
      
  4. Data Fixtures Load fixtures before tests:

    $this->createRepositoryTest(UserRepository::class)
         ->withFixtures([new UserFixture()])
         ->assertFind(1, User::class);
    

Integration Tips

  • Laravel-Specific Mocks: Extend MockEntityManager to support Laravel’s query builder:
    $mockEM = $this->createMockEntityManager();
    $mockEM->expects($this->once())
           ->method('createQueryBuilder')
           ->willReturn(LaravelQueryBuilder::from('users'));
    
  • Transaction Management: Wrap tests in transactions to avoid DB pollution:
    $this->beginTransaction();
    $this->createRepositoryTest(...);
    $this->rollBack();
    

Gotchas and Tips

Pitfalls

  1. EntityManager Mocking

    • Issue: Over-mocking EntityManager can break lazy-loading or event listeners.
    • Fix: Mock only the methods used in tests (e.g., find(), persist()).
  2. Laravel Doctrine Quirks

    • Issue: Laravel’s EntityManager may not fully implement Symfony’s EntityManagerInterface.
    • Fix: Use createMockEntityManager() with partial mocking:
      $mockEM = $this->getMockBuilder(EntityManager::class)
          ->disableOriginalConstructor()
          ->onlyMethods(['find', 'persist'])
          ->getMock();
      
  3. Fixture Loading

    • Issue: Fixtures may not load due to incorrect namespace or missing load() method.
    • Fix: Ensure fixtures implement FixtureInterface and are autoloaded.
  4. Query Builder Assertions

    • Issue: Assertions for custom DQL may fail if the query structure differs slightly.
    • Fix: Use regex or partial matching for flexible assertions:
      $this->assertQueryMatches('/SELECT.*FROM App\Entity\User/', $query);
      

Debugging

  • Enable Debug Mode: Set BEAPP_REPOSITORY_TESTER_DEBUG=true in .env to log query expectations.
  • Verify Mocks: Use var_dump($mockEM->getMockMethods()) to check which methods are mocked.

Extension Points

  1. Custom Assertions Extend RepositoryTestTrait to add domain-specific assertions:

    protected function assertCustomLogic($repository, $input, $expected)
    {
        $result = $repository->customMethod($input);
        $this->assertEquals($expected, $result);
    }
    
  2. 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();
    });
    
  3. 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
            }
        }
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware