Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

loadFixtures() doesn't work with Symfony's dependency injection #12

Open
ThomasLandauer opened this issue Oct 31, 2020 · 5 comments
Open

Comments

@ThomasLandauer
Copy link
Member

When the fixture class is a Symfony service with normal dependency injection (i.e. constructor arguments), loading them with $I->loadFixtures(AppFixtures::class) leads to this error message:

[ArgumentCountError] Too few arguments to function App\DataFixtures\AppFixtures::__construct(), 0 passed in /.../vendor/codeception/module-doctrine2/src/Codeception/Module/Doctrine2.php on line 731 and exactly 4 expected

@TavoNiievez
Copy link
Member

TavoNiievez commented Nov 8, 2020

Hmm...
DataFixtures are not supposed to be services in Symfony, in some projects it's even usually excluded next to the entities and migrations folder, are you sure you don't have them excluded as services in your services.yaml?

@ThomasLandauer
Copy link
Member Author

Well, declaring the fixture class as a service isn't anything special - it's even explained at https://symfony.com/doc/3.1/bundles/DoctrineFixturesBundle/index.html#accessing-services-from-the-fixtures

Your fixtures class is a service, so you can use normal dependency injection:

I'm using it this way to inject some helpers and some Symfony parameters. So yes, I'm sure they're not excluded - otherwise the dependency injection wouldn't work when I load the fixtures :-)

@TavoNiievez
Copy link
Member

TavoNiievez commented Nov 8, 2020

Oh, i see...

It seems i had misinterpreted your problem. I'm sorry.

I've had problems like that before, for example when using Setter Injection in some trait. Try to:

Get the services your fixtures need from the container and create the Fixture object passing them as arguments.

        $service = $this->tester->grabService(Service::class);
        $this->fixtures = new Fixture($service);
        $this->fixtures->load();

Now why those specific services are not injected automatically is a different problem.
I think it may have something to do with the test container configuration... but you will find out if the ->grabService() method does not return the expected object.

@ThomasLandauer
Copy link
Member Author

Here's the workaround I'm using right now:

use Doctrine\Common\DataFixtures\Purger\ORMPurger;
$purger = new ORMPurger($this->entityManager);
$purger->purge();
$this->appFixtures->load($this->entityManager);

This looks easier to me, cause with your way I'd have to manually keep the order of constructor arguments in sync, right?

Now why those specific services are not injected automatically is a different problem.

Well, this is the issue I'm talking about :-)

I think it may have something to do with the test container configuration... but you will find out if the ->grabService() method does not return the expected object.

OK, but which is the expected object? After all, my plan would be not to use ->grabService() at all, but just $I->loadFixtures(AppFixtures::class) to load the fixtures :-)

So would you say this is a bug that can be fixed? Or is this the expected behavior (or just the way it is) - then I'd mention it in the docs of loadFixtures().

@TavoNiievez TavoNiievez transferred this issue from Codeception/module-doctrine2 Feb 17, 2024
TavoNiievez pushed a commit that referenced this issue Feb 17, 2024
Switched to more modern syntax: `User::class` and `[]`
@luninroman
Copy link

Hi guys, is there any update on this? The official doc says it's legit to inject services into fixtures.

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

No branches or pull requests

3 participants