zenstruck / foundry

A model factory library for creating expressive, auto-completable, on-demand dev/test fixtures with Symfony and Doctrine.
https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html
MIT License
608 stars 63 forks source link

[1.x] [upgrade] `ModelFactory` to `ObjectFactory` with services throws `\RuntimeException` #582

Closed jrushlow closed 2 months ago

jrushlow commented 3 months ago

Upgrade w/ rector:

- final class UserFactory extends ModelFactory
+ final class UserFactory extends ObjectFactory
{
    public function __construct(
        private readonly UserPasswordHasherInterface $hasher,
    ) {
        parent::__construct();
    }
...

PHPUnit Output:

PHPUnit 11.0.8 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.3.4
Configuration: /home/jrdev/develop/php/big-desk/phpunit.xml.dist

RuntimeException: Model Factories with dependencies (Model Factory services) cannot be used without the foundry bundle.
/home/jrdev/develop/php/big-desk/vendor/zenstruck/foundry/src/ModelFactoryManager.php:42
/home/jrdev/develop/php/big-desk/vendor/zenstruck/foundry/src/ObjectFactory.php:65
/home/jrdev/develop/php/big-desk/vendor/zenstruck/foundry/src/ObjectFactory.php:126
/home/jrdev/develop/php/big-desk/tests/Functional/Controller/TodoListControllerTest.php:49

Caused by
ArgumentCountError: Too few arguments to function App\Factory\UserFactory::__construct(), 0 passed in /home/jrdev/develop/php/big-desk/vendor/zenstruck/foundry/src/ModelFactoryManager.php on line 40 and exactly 1 expected

/home/jrdev/develop/php/big-desk/src/Factory/UserFactory.php:14
/home/jrdev/develop/php/big-desk/vendor/zenstruck/foundry/src/ModelFactoryManager.php:40
/home/jrdev/develop/php/big-desk/vendor/zenstruck/foundry/src/ObjectFactory.php:65
/home/jrdev/develop/php/big-desk/vendor/zenstruck/foundry/src/ObjectFactory.php:126
/home/jrdev/develop/php/big-desk/tests/Functional/Controller/TodoListControllerTest.php:49

Time: 00:01.525, Memory: 64.50 MB

There was 1 error:

1) App\Tests\Functional\Controller\TodoListControllerTest::testEdit
RuntimeException: Model Factories with dependencies (Model Factory services) cannot be used without the foundry bundle.

/home/jrdev/develop/php/big-desk/vendor/zenstruck/foundry/src/ModelFactoryManager.php:42
/home/jrdev/develop/php/big-desk/vendor/zenstruck/foundry/src/ObjectFactory.php:65
/home/jrdev/develop/php/big-desk/vendor/zenstruck/foundry/src/ObjectFactory.php:126
/home/jrdev/develop/php/big-desk/tests/Functional/Controller/TodoListControllerTest.php:49

Caused by
ArgumentCountError: Too few arguments to function App\Factory\UserFactory::__construct(), 0 passed in /home/jrdev/develop/php/big-desk/vendor/zenstruck/foundry/src/ModelFactoryManager.php on line 40 and exactly 1 expected

/home/jrdev/develop/php/big-desk/src/Factory/UserFactory.php:14
/home/jrdev/develop/php/big-desk/vendor/zenstruck/foundry/src/ModelFactoryManager.php:40
/home/jrdev/develop/php/big-desk/vendor/zenstruck/foundry/src/ObjectFactory.php:65
/home/jrdev/develop/php/big-desk/vendor/zenstruck/foundry/src/ObjectFactory.php:126
/home/jrdev/develop/php/big-desk/tests/Functional/Controller/TodoListControllerTest.php:49

ERRORS!
Tests: 1, Assertions: 0, Errors: 1.
jrushlow commented 3 months ago

Have not dived into yet, but i looks like we need to use reflection to check if there are any constructor arguments (at a minimum, mandatory arguments) right before we call: https://github.com/zenstruck/foundry/blob/d38568f633fddde8065318e1d68c29e9edd32913/src/ModelFactoryManager.php#L40

Then grab those services from the container and instantiate the service. This is of course assuming that ObjectFactory is meant to handle factories w/ services in 2.x. Otherwise rector should check for constructor args, and change ModelFactory to PersistentProxyObjectFactory?