thephpleague / factory-muffin

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

properties referenced in callback are NULL #347

Closed andrewhl closed 9 years ago

andrewhl commented 9 years ago

I'm trying to reference properties defined previously on the model, using the closure you provide. However, $object->amount and $object->created_at, in the example below, are NULL in the callback scope when I var_dump them. As a consequence, 'balance' and 'purchased_at' are NULL when the object is finally created.

Factory::define('GiftCard', [
    'amount'        => 'randomNumber|4',
    'balance'       => function ($object, $saved)
    {
        return $object->amount;
    },
    'created_at'    => 'date|Y-m-d H:i:s',
    'updated_at'    => 'date|Y-m-d H:i:s',
    'purchased_at'  => function ($object, $saved)
    {
        return $object->created_at;
    },
]);

I don't know whether this is relevant or a contributing factor, but I am creating the above factory in the callback of another factory:

Factory::define('GiftCardBatch', [
    'name'        => 'word',
    'description' => 'sentence',
    'type'        => 'word',
    'created_at'  => 'date|Y-m-d H:i:s',
    'updated_at'  => 'date|Y-m-d H:i:s'
], function ($batch, $saved)
{
    $gift_card = Factory::create('GiftCard');
    $batch->gift_cards()->save($gift_card);
});

I am using Codeception and Laravel, and I can also confirm via test screenshot that the balance and purchased_at values are NULL, though everything else is properly defined.

I can get around this issue, in this instance, by manually assigning the values I want in the second callback (e.g., $gift_card->balance = $gift_card->amount), and calling $gift_card->save(). Not really ideal. Any idea what might be causing this?

GrahamCampbell commented 9 years ago

You shouldn't need to set the timestamps manually. Eloquent should be able to do this.

Maybe reading through our eloquent ingregration tests would help you: https://github.com/thephpleague/factory-muffin/blob/2.1/tests/factories/eloquent.php https://github.com/thephpleague/factory-muffin/blob/2.1/tests/EloquentTest.php

GrahamCampbell commented 9 years ago

The timestamps should be passed a DateTime instance rather than a string, (I think).

GrahamCampbell commented 9 years ago

Just re-read your post. This has actually been fixed already, but is only available in the upcoming 3.0 release due the fact we had to change the behaviour to get this to work.