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