Search code examples
symfonycodeception

The test does not see the data from the fixture


I have a fixture to fill in the test user

namespace Tests\Fixture;

use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
use App\Entity\User;

final class UserFixture extends Fixture
{
    public function load(ObjectManager $manager): void
    {
        $userNonAdmin = new User();
        $userNonAdmin->setUsername('uuuuusername');
        $userNonAdmin->setPassword('$2y$10$qk4meHxphpa4qXef6QHC4uNQN/rFsa.iKWdS/8yB.bER1tdkSR6nS'); // hashed 123456
        $userNonAdmin->setEmail('[email protected]');
        $userNonAdmin->setRoles(['ROLE_USER']);
        $manager->persist($userNonAdmin);

        $manager->flush();
    }
}

And a test that uses this fixture

namespace Tests\Acceptance\User;

use Tests\Fixture\UserFixture;
use Tests\Support\AcceptanceTester;

final class UserAuthCest
{
    private const ENDPOINT = '/user/auth';

    public function _before(AcceptanceTester $I): void
    {
        $I->loadFixtures([UserFixture::class]);
    }

    public function positiveTest(AcceptanceTester $I): void
    {
        $data = [
            'username' => 'uuuuusername',
            'password' => '123456'
        ];

        $I->sendPost(self::ENDPOINT, $data);

        $response = $I->grabResponse();

        dd(json_decode($response, true));
    }
}

But as a result, I get the error that the user has not been found, although if I get a UserRepository in the test and try to find the user using this username, then it finds the entity

public function positiveTest(AcceptanceTester $I): void
{
    $data = [
        'username' => 'uuuuusername',
        'password' => '123456'
    ];

    $I->sendPost(self::ENDPOINT, $data);

    /** @var UserRepository $repository */
    $repository = $I->grabRepository(UserRepository::class);
    $user = $repository->findOneBy(['username' => 'uuuuusername']); // Entity exists
    
    $response = $I->grabResponse();

    dd(json_decode($response, true));
}

What am I doing wrong?

Symfony version: 6.3

Codeception version: 5.1.0


Solution

  • I found what the problem was, I had to fix the tests/Acceptance.suite.yml file

    actor: AcceptanceTester
    modules:
        enabled:
            - Doctrine2:
                depends: Symfony
                cleanup: false // <-- replace true with false
    

    And create an extension to automatically clean up your test database

    final class DatabaseMigrationExtension extends Extension
    {
        public static array $events = [
            Events::SUITE_BEFORE => 'beforeSuite',
            Events::SUITE_AFTER => 'afterSuite',
        ];
    
        public function beforeSuite(): void
        {
            try {
                /** @var Cli $cli */
                $cli = $this->getModule('Cli');
                /** @var Symfony $symfony */
                $symfony = $this->getModule('Symfony');
    
                $symfony->_getEntityManager()->getConnection()->close();
    
                $this->writeln('Recreating the database...');
                $cli->runShellCommand('bin/console doctrine:database:drop --if-exists --force');
                $cli->seeResultCodeIs(0);
                $cli->runShellCommand('bin/console doctrine:database:create');
                $cli->seeResultCodeIs(0);
    
                $this->writeln('We are launching migrations...');
                $cli->runShellCommand('bin/console doctrine:migrations:migrate --no-interaction');
                $cli->seeResultCodeIs(0);
    
                $this->writeln('Loading textures...');
                $cli->runShellCommand('php bin/console doctrine:fixtures:load --append --group=test');
                $cli->seeResultCodeIs(0);
    
                $this->writeln('The test base has been created!');
            } catch (Throwable $e) {
                $this->writeln(
                    sprintf(
                        'Error beforeSuite: %s',
                        $e->getMessage()
                    )
                );
            }
        }
    
        public function afterSuite(): void
        {
            try {
                /** @var Cli $cli */
                $cli = $this->getModule('Cli');
    
                $cli->runShellCommand('bin/console doctrine:database:drop --if-exists --force');
                $cli->seeResultCodeIs(0);
                $cli->runShellCommand('bin/console doctrine:database:create');
                $cli->seeResultCodeIs(0);
    
                $this->writeln('The test base has been cleared!');
            } catch (Throwable $e) {
                $this->writeln(
                    sprintf(
                        'Error afterSuite: %s',
                        $e->getMessage()
                    )
                );
            }
        }
    }