Extend Faker in Laravel 11
Sometimes it’s necessary to make your testing data appear as close to the production data as possible. In my case, I wanted more predictable and realistic looking email addresses for system users (they include the company domain and a specific pattern) and other commonly repeated generators.
To extend Faker, first create a provider class to implement your extension code, and a provider to register with the application.
php artisan make:class Faker/CompanyFakesProvider
php artisan make:provider CompanyFakesServiceProvider
In Laravel 11 service providers created through artisan are already registered. Take a look at your bootstrap/providers.php
file to see what I mean.
return [
App\Providers\AppServiceProvider::class,
App\Providers\CompanyFakesServiceProvider::class,
Spatie\Permission\PermissionServiceProvider::class,
];
In your App/Providers/CompanyFakesServiceProvider.php
you’ll want to register a singleton and add the provider to faker.
<?php
namespace App\Providers;
use App\Faker\CompanyFakesProvider;
use Faker\Factory;
use Faker\Generator;
use Illuminate\Support\ServiceProvider;
class FakerServiceProvider extends ServiceProvider
{
/**
* Register services.
*/
public function register(): void
{
$this->app->singleton(Generator::class, function () {
$faker = Factory::create();
$faker->addProvider(new CompanyFakesProvider($faker));
return $faker;
});
}
}
With the class registered and added to faker as a provider, you can now implement your custom methods. In your CompanyFakesProvider.php
file you’ll extend the faker base, then add your methods.
<?php
namespace App\Faker;
use Faker\Provider\Base;
class CompanyFakesProvider extends Base
{
public function companyEmail()
{
return $this->generator->randomLetter() . strtolower($this->generator->lastName()) . '@mycompany.com';
}
public function salesforceId()
{
return $this->generator->regexify('[a-zA-Z0-9]{18}');
}
}
Now I can invoke these methods in my factories like this. database/factories/AccountFactory.php
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Account>
*/
class AccountFactory extends Factory
{
*/
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'id' => $this->faker->salesforceId,
'name' => $this->faker->company,
'owner_id' => $this->faker->salesforceId,
'owner_name' => $this->faker->name,
'owner_email' => $this->faker->companyEmail,
];
}
}
That’s all there is to it! Stay DRY out there folks.