Your Location is: Home > Symfony

Symfony dependency injection or service location for Repositories in PHPUnit tests

From: Salomonen View: 4021 brn 

Question

I'm writing a test for my code in API Platform (built on Symfony 5) and PHPUnit.

I've created a base testcase named TestContext that extends ApiTestCase. All my tests classes will extend TestContext to reuse shared testing boilerplate code.

I'm also trying to use dependency injection (or service location) to resolve the Repository class, so I can access them in all the child classes.

What would be the cleanest, easiest and best-practice way to have access to my Repositories in my test classes?

Best answer

In order to inject the Repository for the API tests I have a src/Test/BaseApiTest.php

namespace App\Test;

use ApiPlatform\Core\Bridge\Symfony\Bundle\Test\ApiTestCase;
use Doctrine\ORM\EntityManagerInterface;
use Hautelook\AliceBundle\PhpUnit\ReloadDatabaseTrait;

class BaseApiTestCase extends ApiTestCase
{
    use ReloadDatabaseTrait;

    protected ?EntityManagerInterface $em;

    protected function setUp(): void
    {
        $kernel = self::bootKernel();

        $this->em = $kernel->getContainer()
            ->get('doctrine')
            ->getManager();
    }
}

Then for the test in my root tests directory I access it as he following:

//tests/UserRessourceTest.php
<?php

namespace App\Tests;

use App\Entity\User;
use App\Test\BaseApiTestCase;

class UserResourceTest extends BaseApiTestCase
{
    public function testDeleteAccount(): void
    {
        ...
        /** @var User $deletedUser */
        $deletedUser = $this->em->getRepository(User::class)->findOneById($user->getId());
        ...
    }
}

This works well for most of my cases. I hope it will work for yours ;)