How to implement a custom Faker Provider in Laravel

In Laravel, factories have access to the Faker PHP library, which allows you to generate all kinds of random data for testing. Here is how to extend Faker to return custom data.

Faker PHP is a library that generates random and anonymized data for testing or to bootstrap an application.

Faker already provides a lot of generator properties, so-called formatters, out of the box. You can find a list of the available formatters in the official documentation.

But what if no formatter aligns with the business logic? In this case, you can register your custom provider to the existing ones. Here's how to do it in Laravel:

Extending the Base

As a simplified example, let's implement a formatter that returns the name of a PHP framework.

A custom provider usually extends the \Faker\Provider\Base class. Therefore, in your Laravel application, create a new class that returns the data:

app/Faker/FrameworkProvider.php
namespace App\Faker;
use Faker\Provider\Base;
class FrameworkProvider extends Base
{
    protected static $names = [
        'CakePHP',
        'CodeIgniter',
        'Laravel',
        'Lumen',
        'Phalcon',
        'Slim',
        'Symfony',
    ];
    public function framework(): string
    {
        return static::randomElement(static::$names);
    }
}

Laravel autoloads the file via Composer. Faker will later use the method name as the name of the formatter. The method returns a random element from a given array of strings.

Extending the Service Provider

Next, register the class in Laravel. You can generate a new Laravel service provider via the artisan command:

php artisan make:provider FakerServiceProvider

Make sure to include the additional Laravel service provider in the config file:

config/app.php
'providers' => [
    App\Providers\FakerServiceProvider::class,
],

In the provider, use the register() method to bind into the service container:

app/Providers/FakerServiceProvider.php
use App\Faker\FrameworkProvider;
use Faker\{Factory, Generator};
use Illuminate\Support\ServiceProvider;
class FakerServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->singleton(Generator::class, function () {
            $faker = Factory::create();
            $faker->addProvider(new FrameworkProvider($faker));
            return $faker;
        });
    }
}

Factory::create() creates a Faker generator bundled with the default providers where you can attach additional providers using the addProvider() method.

Usage in Factories and Tests

Now you can use the new formatter like the other Faker formatters. In a Laravel factory, the syntax for the custom formatter looks like this:

public function definition(): array
{
    return [
        'name' => $this->faker->framework,
    ];
}

A test could look like this:

FrameworkProviderTest.php
use WithFaker;
/** @test */
public function it_matches_any_word(): void
{
    $this->assertMatchesRegularExpression('/\w+/', $this->faker->framework);
}

You can use the formatter in your factories and tests. Keep in mind that fakerphp/faker is a dev dependency in Laravel, which is only available in the development environment.

Summary

Adding custom formatters is a great way to keep test factories short and concise to read whenever you need to generate data that Faker does not represent per default. There are a lot of helpful third-party packages available. I especially like the YouTube URLs package and the package for image placeholders.