thephpleague / factory-muffin

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

How do I get access to the `$fm` variable? #421

Closed benharold closed 8 years ago

benharold commented 8 years ago

I updated to FactoryMuffin 3 because I wanted to update to Faker 1.6 because I wanted to use FactoryMuffinFaker.

With FactoryMuffin 2, I would use League\FactoryMuffin\Facade as FactoryMuffin and then FactoryMuffin::loadFactories(__DIR__ . '/factories'); in my setupBeforeClass method of my base TestCase. I would then use FactoryMuffin statically throughout my test suite. Apparently the facade is gone with version 3.0 and everything must be called from an instance variable, correct?

Anyway, I can't figure out how to get a common instance of FactoryMuffin to persist in my test suite.

I tried changing the FactoryMuffin::loadFactories call into an instance and saving it in my TestCase object, but the setupBeforeClass method is static, so I can't call $this from within.

I tried moving the loadFactories call into the setUp method, but my tests all spit out "The model definition 'App\Object' is undefined".

The README says that the $fm variable will be "made available" upon calling loadFactories. Then a couple of paragraphs later it's talking about calling $fm->loadFactories. What? Where do I call loadFactories?

I looked at the code for the loadFactories method and I have no clue what the $fm declaration is supposed to do. Either this is a paradigm I've never seen before or the $fm declaration does nothing.

private function loadDirectory($path)
{
    $directory = new RecursiveDirectoryIterator($path);
    $iterator = new RecursiveIteratorIterator($directory);
    $files = new RegexIterator($iterator, '/^[^\.](?:(?!\/\.).)+?\.php$/i');

    // what the hell is this supposed to do?
    $fm = $this;

    foreach ($files as $file) {
        require $file->getPathName();
    }
}

The upgrade guide from 2.1 to 3.0 doesn't even mention that the facade is gone, much less that all static calls must now be instance calls. In short, everything is broken and I'm confused. The docs provide contradictory information, and the PHP League website is still on version 2.1.

GrahamCampbell commented 8 years ago

The idea in 3.x is you create the instance, and then keep track of where you want it by yourself.

GrahamCampbell commented 8 years ago
// what the hell is this supposed to do?

$fm = $this;

That sets the $fm fariable to the factory muffin instance so that whne you require each file, that variable is already set, so you can reference it.

benharold commented 8 years ago

Okay now I see what you're doing there. The local $fm variable is available in any loaded factories, because they are being required in that method after you declare $fm, whereas the $fm variable that is used throughout the test suite is the instance variable that it's up to me to create. I mean, technically they are the same object, but the scoping was confusing me. Thanks.