5. Mocking data Factories & seeders - adaptdk/developer-meeting-nova GitHub Wiki
Factories and seeds
A factory and seeding is an easy way to mock a lot of test data into your model. Factories are designed to handle a single model (without or with relationships) and seeders take care of using the factories or other data to actually do the mocking.
Creating factories and table seeders
As with much else we use the command line for this.
For factories
artisan make:factory ModelnameFactory
For seeder
artisan make:seeder ModelnameTableSeeder
This creates files in the folders database/factories/
and database/seeds/
.
Brand seeder
Create the seeder : artisan make:seeder BrandsTableSeeder
Since we know the data we want to use, we can do it by only using the seeder. The BrandsTableSeeder will look like this:
<?php
use App\Brand;
use Illuminate\Database\Seeder;
class BrandsTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$brandNames = [
'Alfa Romeo', 'Aston Martin', 'Audi', 'Bentley', 'BMW', 'Bugatti', 'Chrysler', 'Citroen', 'Ferrari',
'Fiat', 'Honda', 'Hyundai', 'Kia', 'Lamborghini', 'Lancia', 'Land Rover', 'Maserati', 'McLaren',
'Mercedes-Benz', 'Mini', 'Mitsubishi', 'Opel', 'Peugeot', 'Porsche', 'Renault', 'Rolls-Royce', 'Suzuki',
'Toyota', 'Volkswagen'
];
// If you run this multiple times, we truncate it first.
Brand::truncate();
foreach ($brandNames as $brandName) {
Brand::create([
'name' => $brandName
]);
}
}
}
Run the seeder by calling db:seed
artisan db:seed --class=BrandsTableSeeder
Running the seeder
You can run the seeder for a given class by using the --class=SomeTableSeeder parameter, to make it run for a single seeder.
You can also add you custom classes to the DatabaseSeeder in the run() function and the will be triggered when you call
artisan db:seed
Color seeder
Create the seeder : artisan make:seeder ColorsTableSeeder
Pretty much the same as with the BrandsTableSeeder. Looks like this:
<?php
use App\Color;
use Illuminate\Database\Seeder;
class ColorsTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$colors = [
'Unclean Oven Black', 'Given Up Grey', 'Mold Green', 'Poop Brown', 'Bad Rash Red',
'Trump Orange','Black Eye Violet', 'Morning Pee Yellow', 'Blue Waffle Blue',
'Coffee Stain White',
];
// If you run this multiple times, we truncate it first.
Color::truncate();
foreach ($colors as $color) {
Color::create([
'name' => $color
]);
}
}
}
artisan db:seed --class=ColorsTableSeeder
Dealership factory and seeder
Factory
First we create the factory
artisan make:factory DealershipFactory
We want to add data into following attributes : internal_name, street_name and city.
The factories you create using artisan use the faker package. For more info read about The Faker package
Your factory will look like this :
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use App\Dealership;
use Faker\Generator as Faker;
$factory->define(Dealership::class, function (Faker $faker) {
return [
'internal_name' => $faker->state . ' ' . $faker->cityPrefix,
'street_name' => $faker->streetAddress,
'city' => $faker->city
];
});
Seeder
Create the seeder for the dealership
artisan make:seeder DealershipsTableSeeder
Since all the heavy lifting is done in the factory, we just need to initate it.
<?php
use App\Dealership;
use Illuminate\Database\Seeder;
class DealershipsTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$count = 12;
factory(Dealership::class, $count)->create();
}
}
Run the seeder
artisan db:seed --class=DealershipsTableSeeder
Car factory and seeder
Car factory
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use App\Brand;
use App\Car;
use App\Color;
use App\Dealership;
use Faker\Generator as Faker;
$factory->define(Car::class, function (Faker $faker) {
$brands = Brand::all()->pluck('id')->toArray();
$colors = Color::all()->pluck('id')->toArray();
$dealerShips = Dealership::all()->pluck('id')->toArray();
$modelTypes = [
'Electra', 'Jammer', 'Backroad Spinner', 'Discusprolaps',
'Major Wide', 'Titanica', 'Gigantium', 'Nimbbler',
'Puddlepot', 'Deadly Devil', 'Turn-o-lefto', 'Miyagi WaxOff',
'Miygai WaxOn', 'Slipperious', 'Boombox', 'Gert',
'AM Pacific', 'Big Alura', 'Slugger', 'Ugly Speedax',
'North Bear', 'Van Winkle', 'Dragon Force', 'Steamy Windows'
];
$engineTypes = [
'XL', 'XLS', 'GT', 'GTX', 'GTE', 'Electric', 'E-TRON',
'Turbo', '16Valve', 'mit der Einsprizt', 'CDI', 'Intercooler',
'TwinCam', 'CCCX', 'V6', 'V5', 'V8', 'V12', 'Hemi456',
'Hamsterpull', 'Excel XLS'
];
return [
'brand_id' => $faker->randomElement($brands),
'color_id' => $faker->randomElement($colors),
'dealership_id' => $faker->randomElement($dealerShips),
'model_type' => $faker->randomElement($modelTypes) . ' ' . $faker->randomElement($engineTypes),
'description' => $faker->paragraph(10, true),
'created_at' => $faker->dateTimeThisYear,
];
});
Car Seeder
Yes, let's do 150. It's a big thing we are running a proper scale operation.
<?php
use App\Car;
use Illuminate\Database\Seeder;
class CarsTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$count = 150;
factory(Car::class, $count)->create();
}
}
Run the seeder
artisan db:seed --class=CarsTableSeeder
Customer
Customer factory
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use App\Customer;
use Faker\Generator as Faker;
$factory->define(Customer::class, function (Faker $faker) {
return [
'name' => $faker->name
];
});
Customer seeder
<?php
use App\Customer;
use Illuminate\Database\Seeder;
class CustomersTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$count = 5;
factory(Customer::class, $count)->create();
}
}
Run the seeder
artisan db:seed --class=CustomersTableSeeder