Using Laravel model factory for testing

In our daily work we normally develop tests for our application to ensure that the functionalities delivered are reliable and the data management is as real as possible.

As our models (tables) grow in complexity we need a fast and flexible way to test them with mock data to emulate real customer’s data.

In order to accomplish this task Laravel offers since version 5 a Model Factories that basically is a useful technique to create “fake” models patterns. This is what we know as dummy test objects.

Let’s review the basics to see in practice how Model Factories can be used in tests for your Laravel application:

Creating a Model Factory:

You can simply run this artisan command to generate a new Model Factory class

artisan make:factory ModelFactory

The new ModelFactory class will be placed in your database/factories directory.

Note: You can create the factory based on you DB model table with the following command

artisan make:factory ModelFactory --model=User

As a result the ModelFactory.php class will be created. Inside the class a define method is being called on the $factory object with two parameters. The first one is an identifier (Model), used to later reference the factory. The second parameter is a closure which takes in a Faker class and returns an array of users.

$factory->define(App\User::class, function (Faker $faker) {
    return [       
        'email' => $faker->unique()->safeEmail,
        'password' => $password = bcrypt('secret'),
        'dob' => $faker->date('1970-01-01'),
    ];
});

Note: model factories is built based on FAKER php library.

Using the Factory:

To create a single user and save them to the database.

$user = factory(App\User::class, 1)->create();

To create a list of Users just change the amount of intances you need in second parameter

$users = factory(App\User::class, 100)->create();

Override Attributes:

If you want to override some of the default values of your User model, you can pass an array of values to the “create” method.
Only the ‘override’ values will change, while the rest of the ‘default’ values will remain set to their values as specified by the factory.

$user = factory(App\User::class)->create([
    'username' => 'firefighter',
    'email' => '[email protected]',
]);

Test Example:

<?php
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class ExampleTest extends TestCase
{

    use DatabaseTransactions;

    public function testHundredUsersCreated() {
        $users = factory(App\Users::class, 110)->create();
        $userCount = count($users) >= 100;

        $this->assertTrue($userCount);
    }
}

Conclusion:
Model factories are a powerful tool to aid testing and seeding. Having them built into Laravel framework is now one less step in our way for well and consistent testing.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.