Closed tristanbes closed 5 years ago
I will try to reproduce that issue. Stay tuned.
Hi, any news by chance? :-)
Just to be sure, BehatExtension\DoctrineDataFixturesExtension\Bundle\BehatDoctrineDataFixturesExtensionBundle
must be added in your bundle list.
Is it correctly listed?
So, that was indeed a good remark. The bundle wasn't listed in our Kernel.php :s
Adding it doesn't fix the issue though (this->isDebug()
returns true).
if ($this->isDebug()) {
$bundles[] = new Symfony\Bundle\DebugBundle\DebugBundle();
$bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
$bundles[] = new BehatExtension\DoctrineDataFixturesExtension\Bundle\BehatDoctrineDataFixturesExtensionBundle;
}
OK thanks. It looks like there is a real trouble here.
This is a little bit old school, but what if the fixture implements ContainerAwareInterface
?
(not sure this interface is still available)
namespace Context\Fixtures;
...
class FixturesLoader extends Fixture implements ContainerAwareInterface
{
/**
* @var ContainerInterface
*/
private $container;
public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}
/**
* {@inheritdoc}
*/
public function load(ObjectManager $manager)
{
$loader = $this->container->get(NativeLoader::class);
$doctrine = $this->container->get(ManagerRegistry::class);
$objectSet = $loader->loadFiles(
[
__DIR__.'/companies.yml',
__DIR__.'/medias.yml',
In FixturesLoader.php line 49:
Call to a member function get() on null
L49 = $loader = $this->container->get(NativeLoader::class);
class FixturesLoader extends Fixture implements ContainerAwareInterface
{
private $container;
private $doctrine;
public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}
/**
* {@inheritdoc}
*/
public function load(ObjectManager $manager)
{
$loader = $this->container->get(NativeLoader::class);
$doctrine = $this->container->get(ManagerRegistry::class);
$objectSet = $loader->loadFiles(
[
Also, doing so breaks the raw command:
php bin/console doctrine:fixtures:load --env=test
The "Doctrine\Common\Persistence\ManagerRegistry" service or alias has been removed or inlined when the container was compiled. You should either make i
t public, or stop using the container directly and use dependency injection instead.
Can confirm, autowire of constructor arguments is broken.
OK thanks. It looks like there is a real trouble here. This is a little bit old school, but what if the fixture implements
ContainerAwareInterface
? (not sure this interface is still available)namespace Context\Fixtures; ... class FixturesLoader extends Fixture implements ContainerAwareInterface { /** * @var ContainerInterface */ private $container; public function setContainer(ContainerInterface $container = null) { $this->container = $container; } /** * {@inheritdoc} */ public function load(ObjectManager $manager) { $loader = $this->container->get(NativeLoader::class); $doctrine = $this->container->get(ManagerRegistry::class); $objectSet = $loader->loadFiles( [ __DIR__.'/companies.yml', __DIR__.'/medias.yml',
I tried it like that and it seems to work for the first time I run Behat. When I run Behat for the second time it does not autowire services, I need to clear the cache. When I do this it works again. Maybe this will give you a hint on how to fix it.
Hi all,
Sorry for the late answer.
@takeit it only works when the fixture loader is declared as a service, but not when loaded from an arbitrary folder (i.e. with the directories
option).
You can automatically clear your cache using the adamquaile/behat-command-runner-extensio extension.
I am working on a fix, but I have to create my own loader that will wrap the current one and the Symfony one (with container/DI features).
Hi,
I am still looking for a way to make it possible for fixtures loaded by the extension, but at the moment, the only solution to get rid of this issue is to declare the fixtures as services. I created a new branch as POC. There are 3 fixture loaders in the folder DemoBundle/Tests/DataFixtures:
There are all declared as services and, thanks to the autowiring/autoconfiguration from SF, there is nothing complicated.
Can you give it a try and let me know if it works for you? This issue will remain opened until a more convenient solution is found.
Hi @Spomky, thanks a lot, I will give it a try!
For my use case I managed to fix it like that for now: https://github.com/BehatExtension/DoctrineDataFixturesExtension/compare/v5.0...takeit:container_aware?expand=1
Hi @takeit,
I see in your fork that you select either the SF Loader, the Container Aware loader or the default loader. I removed this part as it is not needed anymore: it is useless when fixture loaders are correctly tagged.
The issue still remains regardless which loader is used. Unknown fixtures are either instantiated without any constructor argument or an exception is thrown depending on the loader.
From what I understand, it is not possible to instantiate new classes with DI as the container is already initialized when the extension is called. At this point, private services are not reachable anymore and it is not possible to add new service definition correctly.
I will modify the loader to allow Container-Aware fixtures to be loaded through directories
and fixtures
options.
By the way, it appears to me that the autoload option is useless. The fixtures from the bundles should be declared as services directly by the bundles. I think I will depreciate this option and remove it for v6.x.
Wrap-up:
directories
optionfixtures
optionContainerAwareInterface
) can be loaded
directories
option (next minor release)fixtures
option (next minor release)As mentioned earlier, there is no convenient way to inject the dependencies to fixtures loaders added through the directories
and fixtures
options.
To solve that issue you have to choices:
ContainerAwareInterface
and you get the services you need through that container. In this case these services MUST be public.doctrine.fixture.orm
. All you have to do is to use the Doctrine Fixture Bundle and create your fixture loaders as described in the official documentation.I now close this issue as it is solved from my point of view. Feel free to open it again if you still have troubles with it or contact me to discuss on a private channel (English/French).
The v6.0 I've just released should also help you to move forward.
Hi,
I'm migrating from a Symfony 3 application to
4.1
. It seems that dependency injection is not done. Is this a bug or am I missing something ?The error is:
When i'm running:
bin/behat -c apps/behat.yml -p front --tags="front_intro_on_page"
When I run :
bin/console debug:container FixturesLoader --env=test
it gives meBut when I run
bin/behat -c apps/behat.yml -p front --tags="front_intro_on_page"
The errors appears