zenstruck / foundry

A model factory library for creating expressive, auto-completable, on-demand dev/test fixtures with Symfony and Doctrine.
https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html
MIT License
644 stars 70 forks source link

ResetDatabase deprecation warnings #511

Closed Seb33300 closed 11 months ago

Seb33300 commented 11 months ago

Hello,

I started a new project and tried to use Brower & Foundry for the first time in my tests. I am using the ResetDatabase trait with a SQLite database.

When I run my tests using foundry, I get some deprecation warnings. I did not found any issue about this so I am not sure if you are already aware about it?

  1x: While adding an entity of class App\Entity\Company with an ID hash of "1" to the identity map,
another object of class App\Entity\Company was already present for the same ID. This will trigger
an exception in ORM 3.0.

IDs should uniquely map to entity object instances. This problem may occur if:

- you use application-provided IDs and reuse ID values;
- database-provided IDs are reassigned after truncating the database without
clearing the EntityManager;
- you might have been using EntityManager#getReference() to create a reference
for a nonexistent ID that was subsequently (by the RDBMS) assigned to another
entity.

Otherwise, it might be an ORM-internal inconsistency, please report it.

To opt-in to the new exception, call
\Doctrine\ORM\Configuration::setRejectIdCollisionInIdentityMap on the entity
manager's configuration. (UnitOfWork.php:1696 called by UnitOfWork.php:3923, https://github.com/doctrine/orm/pull/10785, package doctrine/orm)
    1x in CompanyResourceTest::test2 from App\Tests\Functional

Maybe ResetDatabase is not clearing the EntityManager after resetting?

database-provided IDs are reassigned after truncating the database without clearing the EntityManager;

Minimum reproducer:

namespace App\Tests\Functional;

use App\Factory\CompanyFactory;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Zenstruck\Foundry\Test\ResetDatabase;

class CompanyResourceTest extends KernelTestCase
{
    use ResetDatabase;

    public function test1(): void
    {
        CompanyFactory::createOne();
    }

    public function test2(): void
    {
        CompanyFactory::createOne();
    }
}
nikophil commented 11 months ago

Hi @Seb33300

Maybe ResetDatabase is not clearing the EntityManager after resetting?

IMO this is not needed, because the kernel is shutdown directly after the database is reset so a fresh EntityManager is used for each test.

I'm a bit surprized with this problem, we're running the CI with sqlite and we'd be aware of this problem: the entities used in the tests use incremental ids as well.

Any chance you're using https://github.com/dmaicher/doctrine-test-bundle ? not sure this works with sqlite.

Seb33300 commented 11 months ago

Just tried on MySQL 8 and I can also reproduce the issue, so this is not related to SQLite.

This is a fresh Symfony 6.3 install from last week with Api Platform. DAMADoctrineTestBundle is not installed.

Here is my composer.json

    "require": {
        "php": ">=8.1",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "api-platform/core": "^3.2",
        "doctrine/doctrine-bundle": "^2.10",
        "doctrine/doctrine-migrations-bundle": "^3.2",
        "doctrine/orm": "^2.16",
        "lexik/jwt-authentication-bundle": "^2.19",
        "nelmio/cors-bundle": "^2.3",
        "phpdocumentor/reflection-docblock": "^5.3",
        "phpstan/phpdoc-parser": "^1.24",
        "symfony/asset": "*",
        "symfony/console": "*",
        "symfony/dotenv": "*",
        "symfony/expression-language": "*",
        "symfony/flex": "^2",
        "symfony/framework-bundle": "*",
        "symfony/property-access": "*",
        "symfony/property-info": "*",
        "symfony/runtime": "*",
        "symfony/security-bundle": "*",
        "symfony/serializer": "*",
        "symfony/twig-bundle": "*",
        "symfony/validator": "*",
        "symfony/yaml": "*"
    },
    "require-dev": {
        "friendsofphp/php-cs-fixer": "^3.36",
        "mtdowling/jmespath.php": "^2.7",
        "phpstan/phpstan": "^1.10",
        "phpunit/phpunit": "^9.6",
        "symfony/browser-kit": "*",
        "symfony/css-selector": "*",
        "symfony/maker-bundle": "*",
        "symfony/phpunit-bridge": "*",
        "zenstruck/browser": "^1.5",
        "zenstruck/foundry": "^1.36"
    },
kbond commented 11 months ago

I've seen this issue before! Adding the Factories trait to your tests should solve.

Seb33300 commented 11 months ago

OMG! Yes that was the missing trait!

Thanks!