thephpleague / factory-muffin

Enables the rapid creation of objects for testing
https://factory-muffin.thephpleague.com/
MIT License
532 stars 72 forks source link

Added support for Definition::setDefinitions() to accept callback instead of array #438

Closed biserantonov closed 3 years ago

biserantonov commented 7 years ago

There are situations when I need the definitions to be generated prior to instantiation of the model, so I added the option to provide callback instead of array to setDefinitions() method. The callback is responsible to return an array of attributes definitions. For example we can use a $faker instance instead of the facade and do some calculations in isolated space before returning definitions.

$fm->define('definitionscallback:UserModelStub')->setDefinitions(function () use ($faker){
    // do some stuff here

    return [
        'name'    => $faker->word(),
        'active'  => $faker->boolean(),
        'email'   => $faker->email(),
        'age'     => $faker->numberBetween(18, 35),
        'profile' => 'factory|ProfileModelStub',
    ];
});
GrahamCampbell commented 7 years ago

I'm not sure I like this. Note that it's not required to use the faker facade, even without this change, you can still use our actual faker proxy object, to get the lazy behaviour.

biserantonov commented 7 years ago

The faker is just for example. Most often I need to execute some code which will affect several of the attributes definitions, and it's easier to wrap them all in one callback

GrahamCampbell commented 7 years ago

Hmmm, that is true. I'll sleep on it. :)

biserantonov commented 7 years ago

Here is one more suitable example:

$fm->define('Image')->setDefinitions(function () use ($faker){
    $img = $faker->image();
    list($width, $height) = getimagesize($img);
    $size = filesize($img);

    return [
        'path' => $img,
        'width' => $width,
        'height' => $height,
        'size' => $size
    ];
});