Skip to content

Conversation

@tcoch
Copy link
Contributor

@tcoch tcoch commented Jan 12, 2026

When creating tests, getters and setters can be wrong. This PR aims to fix that.

Bug to fix

Creation of `Foo` entity with parameter `foo_foo` - `make:entity` + `make:crud`
root@4f449d2e17c7:/app# bin/console make:entity

 Class name of the entity to create or update (e.g. GentlePuppy):
 > Foo

 created: src/Entity/Foo.php
 created: src/Repository/FooRepository.php
 
 Entity generated! Now let's add some fields!
 You can always add more fields later manually or by re-running this command.

 New property name (press <return> to stop adding fields):
 > foo_foo

 Field type (enter ? to see all types) [string]:
 > 

 Field length [255]:
 > 

 Can this field be null in the database (nullable) (yes/no) [no]:
 > 

 updated: src/Entity/Foo.php

 Add another property? Enter the property name (or press <return> to stop adding fields):
 > 


           
  Success! 
           

 Next: When you're ready, create a migration with php bin/console make:migration
 
root@4f449d2e17c7:/app# bin/console make:crud  

 The class name of the entity to create CRUD (e.g. GentlePizza):
 > Foo

 Choose a name for your controller class (e.g. FooController) [FooController]:
 > 

 Do you want to generate PHPUnit tests? [Experimental] (yes/no) [no]:
 > yes

 created: src/Controller/FooController.php
 created: src/Form/FooType.php
 created: templates/foo/_delete_form.html.twig
 created: templates/foo/_form.html.twig
 created: templates/foo/edit.html.twig
 created: templates/foo/index.html.twig
 created: templates/foo/new.html.twig
 created: templates/foo/show.html.twig
 created: tests/Controller/FooControllerTest.php

           
  Success! 
           

 Next: Check your new CRUD by going to /foo/
Test generated > end up with `setFoo_foo()` / `getFoo_foo()`
<?php

namespace App\Tests\Controller;

use App\Entity\Foo;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

final class FooControllerTest extends WebTestCase
{
    private KernelBrowser $client;
    private EntityManagerInterface $manager;
    private EntityRepository $fooRepository;
    private string $path = '/foo/';

    protected function setUp(): void
    {
        $this->client = static::createClient();
        $this->manager = static::getContainer()->get('doctrine')->getManager();
        $this->fooRepository = $this->manager->getRepository(Foo::class);

        foreach ($this->fooRepository->findAll() as $object) {
            $this->manager->remove($object);
        }

        $this->manager->flush();
    }

    public function testIndex(): void
    {
        $this->client->followRedirects();
        $crawler = $this->client->request('GET', $this->path);

        self::assertResponseStatusCodeSame(200);
        self::assertPageTitleContains('Foo index');

        // Use the $crawler to perform additional assertions e.g.
        // self::assertSame('Some text on the page', $crawler->filter('.p')->first()->text());
    }

    public function testNew(): void
    {
        $this->markTestIncomplete();
        $this->client->request('GET', sprintf('%snew', $this->path));

        self::assertResponseStatusCodeSame(200);

        $this->client->submitForm('Save', [
            'foo[foo_foo]' => 'Testing',
        ]);

        self::assertResponseRedirects($this->path);

        self::assertSame(1, $this->fooRepository->count([]));
    }

    public function testShow(): void
    {
        $this->markTestIncomplete();
        $fixture = new Foo();
        $fixture->setFoo_foo('My Title');

        $this->manager->persist($fixture);
        $this->manager->flush();

        $this->client->request('GET', sprintf('%s%s', $this->path, $fixture->getId()));

        self::assertResponseStatusCodeSame(200);
        self::assertPageTitleContains('Foo');

        // Use assertions to check that the properties are properly displayed.
    }

    public function testEdit(): void
    {
        $this->markTestIncomplete();
        $fixture = new Foo();
        $fixture->setFoo_foo('Value');

        $this->manager->persist($fixture);
        $this->manager->flush();

        $this->client->request('GET', sprintf('%s%s/edit', $this->path, $fixture->getId()));

        $this->client->submitForm('Update', [
            'foo[foo_foo]' => 'Something New',
        ]);

        self::assertResponseRedirects('/foo/');

        $fixture = $this->fooRepository->findAll();

        self::assertSame('Something New', $fixture[0]->getFoo_foo());
    }

    public function testRemove(): void
    {
        $this->markTestIncomplete();
        $fixture = new Foo();
        $fixture->setFoo_foo('Value');

        $this->manager->persist($fixture);
        $this->manager->flush();

        $this->client->request('GET', sprintf('%s%s', $this->path, $fixture->getId()));
        $this->client->submitForm('Delete');

        self::assertResponseRedirects('/foo/');
        self::assertSame(0, $this->fooRepository->count([]));
    }
}

Test generated with fix

Creation of `Bar` entity with parameter `bar_bar` - `make:entity` + `make:crud`
root@4f449d2e17c7:/app# bin/console make:entity

 Class name of the entity to create or update (e.g. FierceElephant):
 > Bar

 created: src/Entity/Bar.php
 created: src/Repository/BarRepository.php
 
 Entity generated! Now let's add some fields!
 You can always add more fields later manually or by re-running this command.

 New property name (press <return> to stop adding fields):
 > bar_bar

 Field type (enter ? to see all types) [string]:
 > 

 Field length [255]:
 > 

 Can this field be null in the database (nullable) (yes/no) [no]:
 > 

 updated: src/Entity/Bar.php

 Add another property? Enter the property name (or press <return> to stop adding fields):
 > 


           
  Success! 
           

 Next: When you're ready, create a migration with php bin/console make:migration
 
root@4f449d2e17c7:/app# bin/console make:crud

 The class name of the entity to create CRUD (e.g. FiercePizza):
 > Bar

 Choose a name for your controller class (e.g. BarController) [BarController]:
 > 

 Do you want to generate PHPUnit tests? [Experimental] (yes/no) [no]:
 > yes

 created: src/Controller/BarController.php
 created: src/Form/BarType.php
 created: templates/bar/_delete_form.html.twig
 created: templates/bar/_form.html.twig
 created: templates/bar/edit.html.twig
 created: templates/bar/index.html.twig
 created: templates/bar/new.html.twig
 created: templates/bar/show.html.twig
 created: tests/Controller/BarControllerTest.php

           
  Success! 
           

 Next: Check your new CRUD by going to /bar/
Test generated > end up with `setBarBar()` / `getBarBar()`
<?php

namespace App\Tests\Controller;

use App\Entity\Bar;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

final class BarControllerTest extends WebTestCase
{
    private KernelBrowser $client;
    private EntityManagerInterface $manager;
    private EntityRepository $barRepository;
    private string $path = '/bar/';

    protected function setUp(): void
    {
        $this->client = static::createClient();
        $this->manager = static::getContainer()->get('doctrine')->getManager();
        $this->barRepository = $this->manager->getRepository(Bar::class);

        foreach ($this->barRepository->findAll() as $object) {
            $this->manager->remove($object);
        }

        $this->manager->flush();
    }

    public function testIndex(): void
    {
        $this->client->followRedirects();
        $crawler = $this->client->request('GET', $this->path);

        self::assertResponseStatusCodeSame(200);
        self::assertPageTitleContains('Bar index');

        // Use the $crawler to perform additional assertions e.g.
        // self::assertSame('Some text on the page', $crawler->filter('.p')->first()->text());
    }

    public function testNew(): void
    {
        $this->markTestIncomplete();
        $this->client->request('GET', sprintf('%snew', $this->path));

        self::assertResponseStatusCodeSame(200);

        $this->client->submitForm('Save', [
            'bar[bar_bar]' => 'Testing',
        ]);

        self::assertResponseRedirects($this->path);

        self::assertSame(1, $this->barRepository->count([]));
    }

    public function testShow(): void
    {
        $this->markTestIncomplete();
        $fixture = new Bar();
        $fixture->setBarBar('My Title');

        $this->manager->persist($fixture);
        $this->manager->flush();

        $this->client->request('GET', sprintf('%s%s', $this->path, $fixture->getId()));

        self::assertResponseStatusCodeSame(200);
        self::assertPageTitleContains('Bar');

        // Use assertions to check that the properties are properly displayed.
    }

    public function testEdit(): void
    {
        $this->markTestIncomplete();
        $fixture = new Bar();
        $fixture->setBarBar('Value');

        $this->manager->persist($fixture);
        $this->manager->flush();

        $this->client->request('GET', sprintf('%s%s/edit', $this->path, $fixture->getId()));

        $this->client->submitForm('Update', [
            'bar[bar_bar]' => 'Something New',
        ]);

        self::assertResponseRedirects('/bar/');

        $fixture = $this->barRepository->findAll();

        self::assertSame('Something New', $fixture[0]->getBarBar());
    }

    public function testRemove(): void
    {
        $this->markTestIncomplete();
        $fixture = new Bar();
        $fixture->setBarBar('Value');

        $this->manager->persist($fixture);
        $this->manager->flush();

        $this->client->request('GET', sprintf('%s%s', $this->path, $fixture->getId()));
        $this->client->submitForm('Delete');

        self::assertResponseRedirects('/bar/');
        self::assertSame(0, $this->barRepository->count([]));
    }
}

@GromNaN
Copy link
Member

GromNaN commented Jan 12, 2026

Good find, thanks for the fix. Could you also add a test case in MakeCrudTest?
You probably need to remove markTestIncomplete for the test to run (see #1774).

Also, the command that uses this template is make:crud? You wrote make:test in the PR title.

@tcoch tcoch changed the title [make:test] Use CamelCase for getter and setter [make:crud] Use CamelCase for getter and setter Jan 12, 2026
@tcoch
Copy link
Contributor Author

tcoch commented Jan 12, 2026

Hi @GromNaN

Could you also add a test case in MakeCrudTest?

I've looked around but I can't seem to find how to test that. My idea would have been to check the generated SweetFoodControllerTest.php file, but I can't find a way to retrieve it / it is currently generated in a random folder :(
Can you help me with that / point me in the right direction please ? How would you do it ?

I fixed the title of the PR, and I got tests running locally.

@GromNaN
Copy link
Member

GromNaN commented Jan 12, 2026

The test must validates that the generated functional test is passing. $this->runCrudTest calls phpunit for in a generated temporary project. You can duplicate this test case:

yield 'it_generates_crud_with_tests' => [$this->createMakerTest()
->addExtraDependencies('symfony/test-pack')
->run(function (MakerTestRunner $runner) {
$runner->copy(
'make-crud/SweetFood.php',
'src/Entity/SweetFood.php'
);
$output = $runner->runMaker([
'SweetFood', // Entity Class Name
'', // Default Controller,
'y', // Generate Tests
]);
$this->assertStringContainsString('src/Controller/SweetFoodController.php', $output);
$this->assertStringContainsString('src/Form/SweetFoodType.php', $output);
$this->assertStringContainsString('tests/Controller/SweetFoodControllerTest.php', $output);
$this->runCrudTest($runner, 'it_generates_basic_crud.php');
}),
];

But use a different entity class that has a property name that reproduces the bug you fixed.

@tcoch
Copy link
Contributor Author

tcoch commented Jan 12, 2026

Thanks to your input @GromNaN , I managed to create a test suite that validates this PR and will prevent the issue from re-appearing.
I also tried to make it easy to possibly validate other stuffs in the future in the new tests/fixtures/make-crud/tests/it_generates_correct_class_methods.php file created (like test the content of the controller form or templates).

I checked locally, if you remove the feature changed in templates/crud/test/Test.EntityManager.tpl.php by this PR, the tests will fail.

@GromNaN GromNaN force-pushed the use-camel-case-for-getter-and-setter branch from 4e80dec to e1e6719 Compare January 13, 2026 10:50
@GromNaN
Copy link
Member

GromNaN commented Jan 13, 2026

Thank you @tcoch.

@GromNaN GromNaN merged commit 1b96b0e into symfony:1.x Jan 13, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants