From 8808c1b7bdbe78ec9b8486e58ad6722cb25eb4e4 Mon Sep 17 00:00:00 2001 From: Matthias Pigulla Date: Wed, 20 Mar 2024 13:45:21 +0100 Subject: [PATCH] Allow passing the mapping driver to `ORMInfrastructure::create*()` methods (#48) This PR makes it possible to transition to attribute-based or other types of Doctrine ORM mapping configuration by (optionally) passing the mapping driver into `ORMInfrastructure::create*()` methods. Also, hybrid configurations (different types of mapping) can be used by leveraging the `MappingDriverChain` from doctrine/persistence. --- README.md | 162 ++++++++++-------- composer.json | 4 +- .../ConfigurationFactory.php | 53 ++++-- .../EntityDependencyResolver.php | 4 +- .../ORMInfrastructure.php | 16 +- .../ExistingConnectionConfigurationTest.php | 2 +- .../ConfigurationFactoryTest.php | 8 - .../EntityWithAttributes/TestEntity.php | 17 ++ .../TestEntityWithDependency.php | 24 +++ .../ORMInfrastructureTest.php | 60 +++++-- 10 files changed, 237 insertions(+), 113 deletions(-) create mode 100644 tests/ORMTestInfrastructure/Fixtures/EntityWithAttributes/TestEntity.php create mode 100644 tests/ORMTestInfrastructure/Fixtures/EntityWithAttributes/TestEntityWithDependency.php diff --git a/README.md b/README.md index 27101d0..c2fb561 100644 --- a/README.md +++ b/README.md @@ -6,18 +6,18 @@ doctrine-orm-test-infrastructure This library provides some infrastructure for tests of Doctrine ORM entities, featuring: - configuration of a SQLite in memory database, compromising well between speed and a database environment being both - realistic and isolated + realistic and isolated - a mechanism for importing fixtures into your database that circumvents Doctrine's caching. This results in a more realistic test environment when loading entities from a repository. [We](https://www.webfactory.de/) use it to test Doctrine repositories and entities in Symfony applications. It's a -lightweight alternative to the heavyweight [functional tests suggested in the Symfony documentation](http://symfony.com/doc/current/cookbook/testing/doctrine.html) -(we don't suggest you should skip those - we just want to open another path). +lightweight alternative to the +heavyweight [functional tests suggested in the Symfony documentation](http://symfony.com/doc/current/cookbook/testing/doctrine.html) +(we don't suggest you should skip those - we just want to open another path). In non-application bundles, where functional tests are not possible, it is our only way to test repositories and entities. - Installation ------------ @@ -25,60 +25,86 @@ Install via composer (see http://getcomposer.org/): composer require --dev webfactory/doctrine-orm-test-infrastructure - Usage ----- - infrastructure = ORMInfrastructure::createWithDependenciesFor(MyEntity::class); + $this->repository = $this->infrastructure->getRepository(MyEntity::class); + } + + /** + * Example test: Asserts imported fixtures are retrieved with findAll(). + */ + public function testFindAllRetrievesFixtures(): void + { + $myEntityFixture = new MyEntity(); + + $this->infrastructure->import($myEntityFixture); + $entitiesLoadedFromDatabase = $this->repository->findAll(); + + /* + import() will use a dedicated entity manager, so imported entities do not + end up in the identity map. But this also means loading entities from the + database will create _different object instances_. + + So, this does not hold: + */ + // self::assertContains($myEntityFixture, $entitiesLoadedFromDatabase); + + // But you can do things like this (you probably want to extract that in a convenient assertion method): + self::assertCount(1, $entitiesLoadedFromDatabase); + $entityLoadedFromDatabase = $entitiesLoadedFromDatabase[0]; + self::assertSame($myEntityFixture->getId(), $entityLoadedFromDatabase->getId()); + } + + /** + * Example test for retrieving Doctrine's entity manager. + */ + public function testSomeFancyThingWithEntityManager(): void { - /** @var ORMInfrastructure */ - private $infrastructure; - - /** @var MyEntityRepository */ - private $repository; - - /** @see \PHPUnit_Framework_TestCase::setUp() */ - protected function setUp() - { - $this->infrastructure = ORMInfrastructure::createWithDependenciesFor(MyEntity::class); - $this->repository = $this->infrastructure->getRepository(MyEntity::class); - } - - /** - * Example test: Asserts imported fixtures are retrieved with findAll(). - */ - public function testFindAllRetrievesFixtures() - { - $myEntityFixture = new MyEntity(); - $this->infrastructure->import($myEntityFixture); - - $entitiesLoadedFromDatabase = $this->repository->findAll(); - - // Please note that you cannot do the following: - // $this->assertContains($myEntityFixture, $entitiesLoadedFromDatabase); - - // But you can do things like this (you probably want to extract that in a convenient assertion method): - $this->assertCount(1, $entitiesLoadedFromDatabase); - $entityLoadedFromDatabase = $entitiesLoadedFromDatabase[0]; - $this->assertEquals($myEntityFixture->getId(), $entityLoadedFromDatabase->getId()); - } - - /** - * Example test for retrieving Doctrine's entity manager. - */ - public function testSomeFancyThingWithEntityManager() - { - $entityManager = $this->infrastructure->getEntityManager(); - // ... - } + $entityManager = $this->infrastructure->getEntityManager(); + // ... } - +} +``` + +Migrating to attribute-based mapping configuration +-------------------------------------------------- + +The `ORMInfrastructure::createWithDependenciesFor()` and ``ORMInfrastructure::createOnlyFor()` methods by default +assume that the Doctrine ORM mapping is provided through annotations. This has been deprecated in Doctrine ORM 2.x +and is no longer be supported in ORM 3.0. + +To allow for a seamless transition towards attribute-based or other types of mapping, a mapping driver can be passed +when creating instances of the `ORMInfrastructure`. + +If you wish to switch to attribute-based mappings, pass a `new \Doctrine\ORM\Mapping\Driver\AttributeDriver($paths)`, +where `$paths` is an array of directory paths where your entity classes are stored. + +For hybrid (annotations and attributes) mapping configurations, you can use `\Doctrine\Persistence\Mapping\Driver\MappingDriverChain`. +Multiple mapping drivers can be registered on the driver chain by providing namespace prefixes. For every namespace prefix, +only one mapping driver can be used. Testing the library itself -------------------------- @@ -92,20 +118,23 @@ need local changes. Happy testing! - ## Changelog ## ### 1.5.0 -> 1.5.1 ### -- Clear entity manager after import to avoid problems with entities detected by cascade operations [(#23)](https://github.com/webfactory/doctrine-orm-test-infrastructure/issues/23) -- Use separate entity managers for imports to avoid interference between import and test phase [(#2)](https://github.com/webfactory/doctrine-orm-test-infrastructure/issues/2) -- Deprecated internal class ``\Webfactory\Doctrine\ORMTestInfrastructure\MemorizingObjectManagerDecorator`` as it is not needed anymore: there are no more selective ``detach()`` calls`after imports +- Clear entity manager after import to avoid problems with entities detected by cascade + operations [(#23)](https://github.com/webfactory/doctrine-orm-test-infrastructure/issues/23) +- Use separate entity managers for imports to avoid interference between import and test + phase [(#2)](https://github.com/webfactory/doctrine-orm-test-infrastructure/issues/2) +- Deprecated internal class ``\Webfactory\Doctrine\ORMTestInfrastructure\MemorizingObjectManagerDecorator`` as it is not needed anymore: there are no + more selective ``detach()`` calls`after imports ### 1.4.6 -> 1.5.0 ### -- Introduced ``ConnectionConfiguration`` to explicitly define the type of database connection [(#15)](https://github.com/webfactory/doctrine-orm-test-infrastructure/pull/15) -- Added support for simple SQLite file databases via ``FileDatabaseConnectionConfiguration``; useful when data must persist for some time, but the connection is reset, e.g. in Symfony's [Functional Tests](http://symfony.com/doc/current/testing.html#functional-tests) - +- Introduced ``ConnectionConfiguration`` to explicitly define the type of database + connection [(#15)](https://github.com/webfactory/doctrine-orm-test-infrastructure/pull/15) +- Added support for simple SQLite file databases via ``FileDatabaseConnectionConfiguration``; useful when data must persist for some time, but the + connection is reset, e.g. in Symfony's [Functional Tests](http://symfony.com/doc/current/testing.html#functional-tests) Create file-backed database: @@ -122,7 +151,6 @@ Create file-backed database: - Ignore associations against interfaces when detecting dependencies via ``ORMInfrastructure::createWithDependenciesFor`` to avoid errors - Exposed event manager and created helper method to be able to register entity mappings - Register entity type mapping: $infrastructure->registerEntityMapping(EntityInterface::class, EntityImplementation::class); @@ -131,7 +159,8 @@ Do not rely on this "feature" if you don't have to. Might be restructured in fut ### 1.4.4 -> 1.4.5 ### -- Fixed bug [#20](https://github.com/webfactory/doctrine-orm-test-infrastructure/issues/20): Entities might have been imported twice in case of bidirectional cascade +- Fixed bug [#20](https://github.com/webfactory/doctrine-orm-test-infrastructure/issues/20): Entities might have been imported twice in case of + bidirectional cascade - Deprecated class ``Webfactory\Doctrine\ORMTestInfrastructure\DetachingObjectManagerDecorator`` (will be removed in next major release) ### 1.4.3 -> 1.4.4 ### @@ -140,12 +169,12 @@ Do not rely on this "feature" if you don't have to. Might be restructured in fut - Dropped support for PHP < 5.5 - Officially support PHP 7 - Known Issues ------------ Please note that apart from any [open issues in this library](https://github.com/webfactory/doctrine-orm-test-infrastructure/issues), you -may stumble upon any Doctrine issues. Especially take care of it's [known sqlite issues](http://doctrine-dbal.readthedocs.org/en/latest/reference/known-vendor-issues.html#sqlite). +may stumble upon any Doctrine issues. Especially take care of +it's [known sqlite issues](http://doctrine-dbal.readthedocs.org/en/latest/reference/known-vendor-issues.html#sqlite). Credits, Copyright and License ------------------------------ @@ -154,9 +183,8 @@ This package was first written by webfactory GmbH (Bonn, Germany) and received [ from other people](https://github.com/webfactory/doctrine-orm-test-infrastructure/graphs/contributors) since then. webfactory is a software development agency with a focus on PHP (mostly [Symfony](http://github.com/symfony/symfony)). -If you're a developer looking for new challenges, we'd like to hear from you! +If you're a developer looking for new challenges, we'd like to hear from you! - -- -Copyright 2012 – 2020 webfactory GmbH, Bonn. Code released under [the MIT license](LICENSE). +Copyright 2012 – 2024 webfactory GmbH, Bonn. Code released under [the MIT license](LICENSE). diff --git a/composer.json b/composer.json index f9ec577..b9741c7 100644 --- a/composer.json +++ b/composer.json @@ -17,13 +17,13 @@ ], "require": { "php": "^7.2|^8.0", - "cache/array-adapter": "^1.0", "doctrine/annotations": "^1.8|^2.0", "doctrine/common": "^2.11|^3.0", "doctrine/dbal": "^2.12|^3.0", "doctrine/event-manager": "^1.1|^2.0", "doctrine/orm": "^2.12", - "doctrine/persistence": "^1.3|^2.0|^3.0" + "doctrine/persistence": "^1.3|^2.0|^3.0", + "symfony/cache": "^4.0|^5.0|^6.0|^7.0" }, "require-dev": { "phpunit/phpunit": "^8.5.36|^9.6.17" diff --git a/src/ORMTestInfrastructure/ConfigurationFactory.php b/src/ORMTestInfrastructure/ConfigurationFactory.php index cfe5eef..96093c1 100644 --- a/src/ORMTestInfrastructure/ConfigurationFactory.php +++ b/src/ORMTestInfrastructure/ConfigurationFactory.php @@ -9,11 +9,14 @@ namespace Webfactory\Doctrine\ORMTestInfrastructure; -use Cache\Adapter\PHPArray\ArrayCachePool; use Doctrine\Common\Annotations\AnnotationReader; +use Doctrine\Common\Annotations\PsrCachedReader; use Doctrine\Common\Annotations\Reader; use Doctrine\ORM\Mapping\Driver\AnnotationDriver; use Doctrine\ORM\ORMSetup; +use Doctrine\Persistence\Mapping\Driver\MappingDriver; +use Psr\Cache\CacheItemPoolInterface; +use Symfony\Component\Cache\Adapter\ArrayAdapter; /** * Creates ORM configurations for a set of entities. @@ -32,6 +35,17 @@ class ConfigurationFactory */ protected static $defaultAnnotationReader = null; + /** @var ?CacheItemPoolInterface */ + private static $metadataCache = null; + + /** @var ?MappingDriver */ + private $mappingDriver; + + public function __construct(MappingDriver $mappingDriver = null) + { + $this->mappingDriver = $mappingDriver; + } + /** * Creates the ORM configuration for the given set of entities. * @@ -40,23 +54,36 @@ class ConfigurationFactory */ public function createFor(array $entityClasses) { - $config = ORMSetup::createConfiguration(true, null, new ArrayCachePool()); + if (self::$metadataCache === null) { + self::$metadataCache = new ArrayAdapter(); + } + + $mappingDriver = $this->mappingDriver ?? $this->createDefaultAnnotationsDriver($entityClasses); - $driver = new AnnotationDriver( - $this->getAnnotationReader(), - $this->getDirectoryPathsForClassNames($entityClasses) - ); - $driver = new EntityListDriverDecorator($driver, $entityClasses); - $config->setMetadataDriverImpl($driver); + $config = ORMSetup::createConfiguration(true, null, new ArrayAdapter()); + $config->setMetadataCache(self::$metadataCache); + $config->setMetadataDriverImpl(new EntityListDriverDecorator($mappingDriver, $entityClasses)); return $config; } + /** + * @param list $entityClasses + * + * @return MappingDriver + */ + private function createDefaultAnnotationsDriver(array $entityClasses) + { + $paths = $this->getDirectoryPathsForClassNames($entityClasses); + + return new AnnotationDriver($this->getAnnotationReader(), $paths); + } + /** * Returns a list of file paths for the provided class names. * - * @param string[] $classNames - * @return string[] + * @param list $classNames + * @return list */ protected function getDirectoryPathsForClassNames(array $classNames) { @@ -70,7 +97,7 @@ protected function getDirectoryPathsForClassNames(array $classNames) /** * Returns the path to the directory that contains the given class. * - * @param string $className + * @param class-string $className * @return string */ protected function getDirectoryPathForClassName($className) @@ -87,9 +114,7 @@ protected function getDirectoryPathForClassName($className) protected function getAnnotationReader() { if (static::$defaultAnnotationReader === null) { - // Use just the reader as the driver depends on the configured - // paths and, therefore, should not be shared. - static::$defaultAnnotationReader = ORMSetup::createDefaultAnnotationDriver()->getReader(); + static::$defaultAnnotationReader = new PsrCachedReader(new AnnotationReader(), new ArrayAdapter()); } return static::$defaultAnnotationReader; diff --git a/src/ORMTestInfrastructure/EntityDependencyResolver.php b/src/ORMTestInfrastructure/EntityDependencyResolver.php index 0f40e40..fe62542 100644 --- a/src/ORMTestInfrastructure/EntityDependencyResolver.php +++ b/src/ORMTestInfrastructure/EntityDependencyResolver.php @@ -49,11 +49,11 @@ class EntityDependencyResolver implements \IteratorAggregate * * @param string[] $entityClasses */ - public function __construct(array $entityClasses) + public function __construct(array $entityClasses, MappingDriver $mappingDriver = null) { $this->initialEntitySet = $this->normalizeClassNames($entityClasses); $this->reflectionService = new RuntimeReflectionService(); - $this->configFactory = new ConfigurationFactory(); + $this->configFactory = new ConfigurationFactory($mappingDriver); } /** diff --git a/src/ORMTestInfrastructure/ORMInfrastructure.php b/src/ORMTestInfrastructure/ORMInfrastructure.php index 73fe768..643ec01 100644 --- a/src/ORMTestInfrastructure/ORMInfrastructure.php +++ b/src/ORMTestInfrastructure/ORMInfrastructure.php @@ -10,6 +10,7 @@ namespace Webfactory\Doctrine\ORMTestInfrastructure; use Doctrine\Common\EventManager; +use Doctrine\Persistence\Mapping\Driver\MappingDriver; use Doctrine\Persistence\ObjectRepository; use Doctrine\Common\Annotations\AnnotationRegistry; use Doctrine\DBAL\Logging\DebugStack; @@ -166,12 +167,9 @@ class ORMInfrastructure * @param ConnectionConfiguration|null $connectionConfiguration Optional, specific database connection information. * @return ORMInfrastructure */ - public static function createWithDependenciesFor( - $entityClassOrClasses, - ConnectionConfiguration $connectionConfiguration = null - ) { + public static function createWithDependenciesFor($entityClassOrClasses, ConnectionConfiguration $connectionConfiguration = null, MappingDriver $mappingDriver = null) { $entityClasses = static::normalizeEntityList($entityClassOrClasses); - return new static(new EntityDependencyResolver($entityClasses), $connectionConfiguration); + return new static(new EntityDependencyResolver($entityClasses, $mappingDriver), $connectionConfiguration, $mappingDriver); } /** @@ -184,9 +182,9 @@ public static function createWithDependenciesFor( * @param ConnectionConfiguration|null $connectionConfiguration Optional, specific database connection information. * @return ORMInfrastructure */ - public static function createOnlyFor($entityClassOrClasses, ConnectionConfiguration $connectionConfiguration = null) + public static function createOnlyFor($entityClassOrClasses, ConnectionConfiguration $connectionConfiguration = null, MappingDriver $mappingDriver = null) { - return new static(static::normalizeEntityList($entityClassOrClasses), $connectionConfiguration); + return new static(static::normalizeEntityList($entityClassOrClasses), $connectionConfiguration, $mappingDriver); } /** @@ -213,7 +211,7 @@ protected static function normalizeEntityList($entityClassOrClasses) * @param ConnectionConfiguration|null $connectionConfiguration Optional, specific database connection information. * @deprecated Use one of the create*For() factory methods. */ - public function __construct($entityClasses, ConnectionConfiguration $connectionConfiguration = null) + public function __construct($entityClasses, ConnectionConfiguration $connectionConfiguration = null, MappingDriver $mappingDriver = null) { // Register the annotation loader before the dependency discovery process starts (if required). // This ensures that the annotation loader is available for the entity resolver that reads the annotations. @@ -229,7 +227,7 @@ public function __construct($entityClasses, ConnectionConfiguration $connectionC $this->connectionConfiguration = $connectionConfiguration; $this->queryLogger = new DebugStack(); $this->namingStrategy = new DefaultNamingStrategy(); - $this->configFactory = new ConfigurationFactory(); + $this->configFactory = new ConfigurationFactory($mappingDriver); $this->resolveTargetListener = new ResolveTargetEntityListener(); $this->eventSubscribers = [$this->resolveTargetListener]; diff --git a/tests/Config/ExistingConnectionConfigurationTest.php b/tests/Config/ExistingConnectionConfigurationTest.php index 45dfbc7..566d20b 100644 --- a/tests/Config/ExistingConnectionConfigurationTest.php +++ b/tests/Config/ExistingConnectionConfigurationTest.php @@ -40,7 +40,7 @@ protected function setUp(): void public function testWorksWithInfrastructure() { $infrastructure = ORMInfrastructure::createOnlyFor( - [TestEntity::class], + array(TestEntity::class), $this->connectionConfiguration ); diff --git a/tests/ORMTestInfrastructure/ConfigurationFactoryTest.php b/tests/ORMTestInfrastructure/ConfigurationFactoryTest.php index 62269f0..7cf4c5d 100644 --- a/tests/ORMTestInfrastructure/ConfigurationFactoryTest.php +++ b/tests/ORMTestInfrastructure/ConfigurationFactoryTest.php @@ -35,14 +35,6 @@ protected function setUp(): void $this->factory = new ConfigurationFactory(); } - /** - * Cleans up the test environment. - */ - protected function tearDown(): void - { - $this->factory = null; - parent::tearDown(); - } /** * Ensures that createFor() returns an ORM configuration object. */ diff --git a/tests/ORMTestInfrastructure/Fixtures/EntityWithAttributes/TestEntity.php b/tests/ORMTestInfrastructure/Fixtures/EntityWithAttributes/TestEntity.php new file mode 100644 index 0000000..b90fa52 --- /dev/null +++ b/tests/ORMTestInfrastructure/Fixtures/EntityWithAttributes/TestEntity.php @@ -0,0 +1,17 @@ +dependency = new ReferencedEntity(); + } +} diff --git a/tests/ORMTestInfrastructure/ORMInfrastructureTest.php b/tests/ORMTestInfrastructure/ORMInfrastructureTest.php index f769d1e..a7a9437 100644 --- a/tests/ORMTestInfrastructure/ORMInfrastructureTest.php +++ b/tests/ORMTestInfrastructure/ORMInfrastructureTest.php @@ -9,12 +9,16 @@ namespace Webfactory\Doctrine\Tests\ORMTestInfrastructure; +use Doctrine\Common\Annotations\AnnotationReader; use Doctrine\Common\Annotations\AnnotationRegistry; use Doctrine\Common\EventManager; use Doctrine\DBAL\Schema\Schema; use Doctrine\ORM\EntityManager; use Doctrine\ORM\Mapping\ClassMetadataInfo; +use Doctrine\ORM\Mapping\Driver\AnnotationDriver; +use Doctrine\ORM\Mapping\Driver\AttributeDriver; use Doctrine\ORM\Tools\SchemaTool; +use Doctrine\Persistence\Mapping\Driver\MappingDriverChain; use PHPUnit\Framework\TestCase; use Webfactory\Doctrine\Config\ConnectionConfiguration; use Webfactory\Doctrine\ORMTestInfrastructure\ORMInfrastructure; @@ -32,7 +36,8 @@ use Webfactory\Doctrine\Tests\ORMTestInfrastructure\Fixtures\EntityWithAnnotation\TestEntity; use Webfactory\Doctrine\Tests\ORMTestInfrastructure\Fixtures\EntityWithAnnotation\TestEntityRepository; use Webfactory\Doctrine\Tests\ORMTestInfrastructure\Fixtures\EntityWithAnnotation\TestEntityWithDependency; - +use Webfactory\Doctrine\Tests\ORMTestInfrastructure\Fixtures\EntityWithAttributes\TestEntity as TestEntity_Attributes; +use Webfactory\Doctrine\Tests\ORMTestInfrastructure\Fixtures\EntityWithAttributes\TestEntityWithDependency as TestEntityWithDependency_Attributes; /** * Tests the infrastructure. @@ -57,15 +62,6 @@ protected function setUp(): void )); } - /** - * Cleans up the test environment. - */ - protected function tearDown(): void - { - $this->infrastructure = null; - parent::tearDown(); - } - /** * Checks if getEntityManager() returns the Doctrine entity manager, */ @@ -138,6 +134,26 @@ public function testImportAddsEntities() $this->assertCount(1, $entities); } + public function testImportEntityWithAttributeMapping() + { + if (PHP_VERSION_ID < 80000) { + self::markTestSkipped('This test requires PHP 8.0 or greater'); + } + + $this->infrastructure = new ORMInfrastructure([TestEntity_Attributes::class], null, new AttributeDriver([__DIR__.'/Fixtures/EntityWithAttributes'])); + + $entity = new TestEntity_Attributes(); + $repository = $this->infrastructure->getRepository($entity); + + $entities = $repository->findAll(); + $this->assertCount(0, $entities); + + $this->infrastructure->import($entity); + + $entities = $repository->findAll(); + $this->assertCount(1, $entities); + } + /** * Checks if an imported entity receives a generated ID. */ @@ -331,6 +347,30 @@ public function testInfrastructureAutomaticallyPerformsDependencySetupIfRequeste ); } + /** + * Ensures that referenced sub-entities are automatically prepared if the infrastructure is + * requested to handle such cases. + */ + public function testInfrastructureAutomaticallyPerformsDependencySetupAcrossMappingDrivers() + { + if (PHP_VERSION_ID < 80000) { + self::markTestSkipped('This test requires PHP 8.0 or greater'); + } + + $mappingDriver = new MappingDriverChain(); + $mappingDriver->addDriver(new AnnotationDriver(new AnnotationReader(), [__DIR__.'/Fixtures/EntityWithAnnotation']), 'Webfactory\Doctrine\Tests\ORMTestInfrastructure\Fixtures\EntityWithAnnotation'); + $mappingDriver->addDriver(new AttributeDriver([__DIR__.'/Fixtures/EntityWithAttributes']), 'Webfactory\Doctrine\Tests\ORMTestInfrastructure\Fixtures\EntityWithAttributes'); + + $this->infrastructure = ORMInfrastructure::createWithDependenciesFor([TestEntityWithDependency_Attributes::class], null, $mappingDriver); + + $entityWithDependency = new TestEntityWithDependency_Attributes(); + + self::expectNotToPerformAssertions(); + + $this->infrastructure->getEntityManager()->persist($entityWithDependency); + $this->infrastructure->getEntityManager()->flush(); + } + /** * Checks if the automatic dependency setup can cope with reference cycles, * for example if an entity references itself.