foundry
foundry copied to clipboard
Remove doctrine event listeners/subscribers temporarily
I have an issue with some testing cases:
- When i want to test my doctrine event subscribers in a functional test, I want predefined data to perform a PUT request. My subscribers are fired when i instantiate foundry fixtures, so i could verify nothing with my call.
- Same for Functional tests on symfony command
So sometimes I would like to store fixtures that goes raw in database, without any listeners on their creation.
Maybe we can already does it, but I didn't found how, So I made a little code snippet for that:
use Doctrine\Bundle\DoctrineBundle\EventSubscriber\EventSubscriberInterface;
use Doctrine\ORM\EntityManagerInterface;
...
public function withoutDoctrineListeners()
{
/** @var EntityManagerInterface $manager */
$manager = FooFactory::configuration()->objectManagerFor(Foo::class);
$listeners = $manager->getConnection()->getEventManager()->getListeners();
foreach ($listeners as $type => $listenersByType) {
foreach ($listenersByType as $listener) {
if ($listener instanceof EventSubscriberInterface) {
$manager->getConnection()->getEventManager()->removeEventSubscriber($listener);
continue;
}
$manager->getConnection()->getEventManager()->removeEventListener($type, $listener);
}
}
}
So do you think is it something you can propose in foundry ?
I thought about something like (function name is probably bad):
FooFactory::new()->withoutDoctrineListeners()->create();
I can submit a pull request if you like the idea
I do like the idea but there are some nuances we need to think about.
When calling your code that actually tests the listeners, do you do anything to put the event listeners "back"?
Here's (I think) 1 problem:
$factory = FooFactory::new()->withoutDoctrineListeners();
$factory->create(); // creates entity without event listeners
// shutdown/restart kernel
$factory->create(); // creates entity WITH event listeners
Here's another:
FooFactory::new()->withoutDoctrineListeners()->create(); // creates entity without event listeners
BarFactory::new()->create(); // also creates entity without event listeners (this is unexpected)
I believe a solution could be:
-
->withoutDoctrineListeners()
sets a flag on the factory -
->create()
checks for flag before creation, if flag set:- Remove listeners/subscribers
- do create
- Re-add removed listeners/subscribers
Yeah I agree with that, we need to put back listeners after creation.
I thought about something else, the function could have an optional argument, "$eventTypeName":
FooFactory::new()->withoutDoctrineListeners(Events::postPersist)->create();
The function "getListeners" have this optional argument, so it would be nice to allow it and follow it to this function.
Do you want to add the feature yourself, or it is ok for you to let me make a pull request for this ?
I thought about something else, the function could have an optional argument, "$eventTypeName":
Sure, makes sense.
or it is ok for you to let me make a pull request for this
Go ahead with a PR if you're willing!