Codeception / module-datafactory

DataFactory module for Codeception
MIT License
8 stars 7 forks source link

Can't use existing entities with DataFactory #4

Open CJDennis opened 4 years ago

CJDennis commented 4 years ago

What are you trying to achieve?

According to https://codeception.com/docs/modules/DataFactory.html you can create a new entity which is related to an existing entity. I can't get this functionality to work.

What do you get instead?

  [Doctrine\ORM\ORMInvalidArgumentException] A new entity was found through the relationship 'HMRX\CoreBundle\Entity\AccountHolder#accountRole' that was not configured to cascade persist operations for entity: HMRX\CoreBundle\Entity\AccountRole@000000004c9582ff000000009565e70e. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist  this association in the mapping for example @ManyToOne(..,cascade={"persist"}). If you cannot find out which entity causes the problem implement 'HMRX\CoreBundle\Entity\AccountRole#__toString()' to get a clue.

Provide test source code if related

  public function shouldUseAFakeAccountHolder(AcceptanceTester $I) {
    $I->have(AccountHolder::class);
  }
class Factories extends \Codeception\Module {
  public function _beforeSuite($settings = []) {
    /** @var EntityManager $em */
    $em = $this->getModule('Doctrine2')->_getEntityManager();

    $factory = $this->getModule('DataFactory');

    $factory->_define(AccountHolder::class, [
      'accountRole' => $em->getRepository(AccountRole::class)->findOneBy(['name' => 'ROLE_PHARMACIST']),
    ]);
  }
}

Details

# Codeception Test Suite Configuration
#
# Suite for acceptance tests.
# Perform tests in browser using the WebDriver or PhpBrowser.
# If you need both WebDriver and PHPBrowser tests - create a separate suite.

actor: AcceptanceTester
modules:
  enabled:
    - WebDriver:
        url: 'https://localhost/'
        browser: chrome # 'chrome' or 'firefox'
        capabilities:
          chromeOptions:
            w3c: false
    - \Helper\Acceptance
    - Doctrine2:
        depends: Symfony
    - DataFactory:
        depends: Doctrine2
        factories: tests/_support/Factories
    - \Helper\Factories
Liiva commented 4 years ago

I don't know why exactly but wrapping the $em->getRepository(...) call in a closure seems to fix this issue for me, e.g.:

'accountRole' => function() use ($em) {
    return $em->getRepository(AccountRole::class)->findOneBy(['name' => 'ROLE_PHARMACIST']);
}

I'm guessing the closure is executed at a different point in the execution flow.

raph007 commented 3 years ago

@Liiva Thank you! You saved me so much time. :) I've been struggling with this for over 2 hours.

@DavertMik Maybe it is good idea to add this to docs?