I have this model factory that generates new contact, it uses random company_id
:
$factory->define(App\Models\Contact::class, function (Faker\Generator $faker)
{
$company_id = Company::all()->random()->id;
return [
'firstname' => $faker->firstName,
'lastname' => $faker->lastName,
'phone' => $faker->phoneNumber,
'email' => $faker->email,
'company_id' => $company_id,
'lead_id' => \App\Models\Lead::where('company_id', $company_id)->get()->random()->id,
];
});
It is ok when I use it in seeds:
factory(App\Models\Contact::class)->create();
But for testing I need somehow to pass $company_id
to factory, create contact for concrete company_id
(I know that I can do ->create(['company_id', $company_id])
) but this will rewrite only company_id from Contact.
When I select lead_id
, I also need to know current company_id
.
How to pass company_id to factory as parameter?
Let’s review the basics to see in practice how Model Factories can be used in tests for your Laravel application: You can simply run this artisan command to generate a new Model Factory class The new ModelFactory class will be placed in your database/factories directory.
Dawid Janik comes up with a package called Laravel Factory Generator. This package will generate factories from your existing models. That way you can get started with testing your Laravel or Lumen application more quickly! It is a forked version of mpociot/laravel-test-factory-helper package.
* Define the model's default state. As you can see, in their most basic form, factories are classes that extend Laravel's base factory class and define a definition method. The definition method returns the default set of attribute values that should be applied when creating a model using the factory.
Instead, you can use model factories to generate large amounts of database records conveniently. Laravel has a feature called model factories that allow us to generate fake data. It is beneficial for testing and seeding fake data into the database to see the code in action before any real-time user data comes into your application.
Try to use this example:
$factory->define(App\Models\Contact::class, function ($faker, $params) {
$company_id = $params['company_id'];
....
});
and this to make a new object:
$newContact = factory(App\Models\Contact::class)->make(['company_id' => $current_company_id]);
Depends on your Laravel version it will be different.
For laravel 5.1 https://github.com/laravel/framework/issues/9245
You will need to check if is passed manually
// Testcase
$company = factory(App\Models\Company::class)->create();
factory(App\Models\Contact::class)->create(['company_id' => $company->id]);
// Factory
$factory->define(App\Models\Contact::class, function (Faker\Generator $faker, $attribues) {
// Manually check if id is passed
$company_id = (isset($attribues['company_id'])) ?: Company::all()->random()->id;
return [
'firstname' => $faker->firstName,
'lastname' => $faker->lastName,
'phone' => $faker->phoneNumber,
'email' => $faker->email,
'company_id' => $company_id,
'lead_id' => \App\Models\Lead::where('company_id', $company_id)->get()->random()->id,
];
});
For Laravel 5.2 and above you can simply pass id https://laravel.com/docs/5.5/database-testing#relationships
// Testcase
$company = factory(App\Models\Company::class)->create();
factory(App\Models\Contact::class)->create(['company_id' => $company->id]);
// Factory
$factory->define(App\Models\Contact::class, function (Faker\Generator $faker, $attribues) {
// Manually check if id is passed
$company_id = (isset($attribues['company_id'])) ?: Company::all()->random()->id;
return [
'firstname' => $faker->firstName,
'lastname' => $faker->lastName,
'phone' => $faker->phoneNumber,
'email' => $faker->email,
'company_id' => function(){
return factory(\App\Models\Company::class)->create()
},
'lead_id' => \App\Models\Lead::where('company_id', $company_id)->get()->random()->id,
];
});
So, for your case, get your random company_id first and pass it to factory. Depends on your Larval version change the ContactModel factory. Or if you have relation that you can query, you can do it as well.
// If you have a relation
$contact = factory(App\Models\Contact::class)->create();
$company_id = $contact->company->id;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With