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 Core Laravel Package

beapp/repository-tester-core

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the package to your Laravel project via Composer:

    composer require beapp/repository-tester-core
    

    For Laravel, ensure compatibility by using a Symfony bridge like symfony/http-foundation if needed.

  2. Basic Configuration Register the bundle in config/app.php (if using Laravel's Symfony bridge) or configure it via a service provider:

    // config/testing.php (example)
    'repository_tester' => [
        'doctrine' => [
            'entity_manager' => 'default', // Match your Laravel DB connection
        ],
    ],
    
  3. First Test Case Create a test class extending BeApp\RepositoryTesterCore\TestCase\RepositoryTestCase:

    use BeApp\RepositoryTesterCore\TestCase\RepositoryTestCase;
    use App\Repository\UserRepository;
    
    class UserRepositoryTest extends RepositoryTestCase
    {
        protected function getRepository(): UserRepository
        {
            return $this->getEntityManager()->getRepository(UserRepository::class);
        }
    
        public function testFindById()
        {
            $user = $this->getRepository()->find(1);
            $this->assertInstanceOf(User::class, $user);
        }
    }
    
  4. Key Files to Review

    • src/TestCase/RepositoryTestCase.php (base class)
    • src/Traits/RepositoryTestTrait.php (shared methods)
    • README.md on the main repository-tester.web repo.

Implementation Patterns

Core Workflow

  1. Repository Isolation Use RepositoryTestCase to mock the entire repository layer without hitting the database:

    public function testFindAll()
    {
        $this->mockRepository()
             ->method('findAll')
             ->willReturn([new User()]);
    
        $result = $this->getRepository()->findAll();
        $this->assertCount(1, $result);
    }
    
  2. Data Fixtures Load test data via YAML/array fixtures:

    protected function getFixtures(): array
    {
        return [
            'users' => [
                ['id' => 1, 'name' => 'John'],
                ['id' => 2, 'name' => 'Jane'],
            ],
        ];
    }
    
  3. Assertion Helpers Leverage built-in assertions for Doctrine queries:

    public function testFindOneBy()
    {
        $this->assertOneResult(
            $this->getRepository()->findBy(['name' => 'John'])
        );
    }
    
  4. Integration with Laravel

    • Service Container: Bind the EntityManager manually if not using Symfony:
      $this->app->bind('doctrine.entity_manager', function () {
          return \Doctrine\ORM\EntityManager::create([...], $config);
      });
      
    • Database Transactions: Use Laravel’s refreshDatabase() or migrate() in setUp():
      public function setUp(): void
      {
          parent::setUp();
          $this->artisan('migrate:fresh');
      }
      
  5. Custom Query Testing Test complex DQL/QueryBuilder logic:

    public function testCustomQuery()
    {
        $qb = $this->getRepository()->createQueryBuilder('u');
        $qb->where('u.name LIKE :name')->setParameter('name', '%John%');
    
        $this->assertCount(1, $qb->getQuery()->getResult());
    }
    

Gotchas and Tips

Pitfalls

  1. Doctrine vs. Eloquent

    • The package is Doctrine-specific. For Eloquent, consider mocking repositories manually or using DatabaseMigrations + DatabaseTransactions.
    • Avoid mixing EntityManager and Eloquent’s Model::query() in the same test.
  2. Fixture Loading

    • Fixtures are not auto-loaded by default. Explicitly call:
      $this->loadFixtures();
      
    • Ensure fixture data matches your entity mappings (e.g., @ORM\Id fields).
  3. Mocking Quirks

    • Partial Mocks: Use partialMock() for repositories with complex dependencies:
      $this->mockRepository()->partialMock();
      
    • Method Overrides: If a method is overridden in a child repository, mock the child class explicitly.
  4. Performance

    • Avoid Real DB Calls: Even with transactions, complex fixtures can slow tests. Prefer in-memory mocks for unit tests.

Debugging Tips

  1. Enable Doctrine Logging Add to setUp() to debug queries:

    $this->getEntityManager()->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger());
    
  2. Verify Fixtures Dump loaded fixtures for debugging:

    $this->getEntityManager()->createQuery('SELECT u FROM App\Entity\User u')->getResult();
    
  3. Symfony Bridge Issues

    • If using Laravel, ensure symfony/dependency-injection and symfony/http-kernel are installed.
    • For kernel tests, bind the HttpKernel manually:
      $this->app->singleton('http_kernel', function () {
          return new \Symfony\Component\HttpKernel\HttpKernel(
              $this->app->make('kernel'),
              'test'
          );
      });
      

Extension Points

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

    class CustomRepositoryTest extends RepositoryTestCase
    {
        protected function assertUserExists(User $user)
        {
            $this->assertNotNull(
                $this->getRepository()->find($user->getId())
            );
        }
    }
    
  2. Fixture Factories Create reusable fixture factories:

    class UserFixtureFactory
    {
        public static function create(int $id, string $name): array
        {
            return ['id' => $id, 'name' => $name];
        }
    }
    
  3. Hybrid Testing Combine with Laravel’s RefreshDatabase for integration tests:

    use Illuminate\Foundation\Testing\RefreshDatabase;
    
    class UserRepositoryIntegrationTest extends RepositoryTestCase
    {
        use RefreshDatabase;
    
        // Test real DB interactions here
    }
    
  4. Parallel Testing Use pestphp/pest or phpunit-parallel with caution—Doctrine’s EntityManager may not be thread-safe by default. Isolate tests with unique fixtures.

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.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor