Skip to content

[Doctrine] ManyToMany Relationships not persisted in database with haveInRepository nested entity creation #16

Open
@Pryrios

Description

@Pryrios

What are you trying to achieve?

I am running a functional test on a Symfony 4 + Doctrine 2 with two entities with a ManyToMany relationship. I create the entities using haveInRepository nested functionality and I expect to have the two entities created on the database and related on the join table.

What do you get instead?

The entities are created but relationships in join tables are not, so the test fails due to missing information on database.

Provide console output if related. Use -vvv mode for more details.

vagrant@symfonyvm:/var/www/mtm$ php vendor/bin/codecept run
Codeception PHP Testing Framework v3.1.2
Powered by PHPUnit 8.5.0 by Sebastian Bergmann and contributors.
Running with seed: 


App\Tests.acceptance Tests (0) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

App\Tests.functional Tests (1) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Testing App\Tests.functional
✖ ManytoManyEntitiesCest: Try to test (0.07s)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

App\Tests.unit Tests (0) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Time: 326 ms, Memory: 28.25 MB

There was 1 failure:

---------
1) ManytoManyEntitiesCest: Try to test
 Test  tests/functional/ManytoManyEntitiesCest.php:tryToTest
 Step  See in repository "App\Entity\EntityA",{"entityB":{"name":"Name B"}}
 Fail  App\Entity\EntityA with {"entityB":{"name":"Name B"}}
Failed asserting that false is true.

Scenario Steps:

 4. $I->seeInRepository("App\Entity\EntityA",{"entityB":{"name":"Name B"}}) at tests/functional/ManytoManyEntitiesCest.php:24
 3. $I->seeInRepository("App\Entity\EntityA",{"name":"Name A"}) at tests/functional/ManytoManyEntitiesCest.php:23
 2. $I->seeInRepository("App\Entity\EntityB",{"name":"Name B"}) at tests/functional/ManytoManyEntitiesCest.php:22
 1. $I->haveInRepository("App\Entity\EntityA",{"name":"Name A","entityB":[{"name":"Name B"}]}) at tests/functional/ManytoManyEntitiesCest.php:19


FAILURES!
Tests: 1, Assertions: 3, Failures: 1.

Provide test source code if related

<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\EntityARepository")
 */
class EntityA
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $name;

    /**
     * @ORM\ManyToMany(targetEntity="App\Entity\EntityB", inversedBy="entityA")
     */
    private $entityB;
}
<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\EntityBRepository")
 */
class EntityB
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $name;

    /**
     * @ORM\ManyToMany(targetEntity="App\Entity\EntityA", mappedBy="entityB")
     */
    private $entityA;
}
public function cannotSeeManyToManyRelationships(FunctionalTester $I)
{
    $I->haveInRepository(
        EntityA::class,
        [
            'name' => 'Name A',
            'entityB' =>[[ 'name' => 'Name B' ]],
        ]);
    $I->seeInRepository(EntityB::class, ['name' => 'Name B']);
    $I->seeInRepository(EntityA::class, ['name' => 'Name A']);
    $I->seeInRepository(EntityA::class, ['entityB' => ['name' => 'Name B']]);
}

Details

With that setup, the two first seeInRepository pass but the third does not. It could be due to the syntax of the array not being correct on the last assertion as it should really be an array, but if you look into the database you can see that the join table has not been filled.

It may be due a syntax problem, but in that case it should be an issue with docs as it doesn't specify how to work with ManyToMany relationships.

I have created a complete example in this repo: https://github.com/Pryrios/test-manytomany

  • Codeception version: Codeception PHP Testing Framework v3.1.2
  • PHP Version: 7.2
  • Operating System: Ubuntu 18.04
  • Installation type: Composer

functional.suite.yml

actor: FunctionalTester
modules:
    enabled:
        - Symfony:
            app_path: 'src'
            environment: 'test'
        - Doctrine2:
           depends: Symfony
           cleanup: true
        - \App\Tests\Helper\Functional

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions