league/factory-muffin-faker
Wraps Faker generators in deferred closures for easy use with Factory Muffin or any factory setup. Lets you define attributes with Faker and execute generation later, keeping factories simple and flexible. Compatible with PHP 5.4+ via Composer.
Installation:
composer require-dev league/factory-muffin-faker
Add to composer.json under "require-dev":
"league/factory-muffin-faker": "^2.3"
Basic Usage:
Register the provider in your test setup (e.g., setUp() in a test case or a service provider):
use League\FactoryMuffin\FactoryMuffin;
use League\FactoryMuffinFaker\FactoryMuffinFaker;
$factory = new FactoryMuffin();
$factory->registerProvider(new FactoryMuffinFaker());
First Use Case:
Define a factory for a User model with Faker-generated data:
$factory->define(User::class, function () {
return [
'name' => $this->faker->name,
'email' => $this->faker->unique()->safeEmail,
'password' => $this->faker->password,
];
});
Use it in tests:
$user = $factory->create(User::class);
Factory Definition with Faker: Leverage Faker’s methods directly in factory definitions:
$factory->define(Product::class, function () {
return [
'name' => $this->faker->catchPhrase,
'price' => $this->faker->randomFloat(2, 10, 1000),
'description' => $this->faker->paragraph,
];
});
Lazy Evaluation: Use closures for deferred generation (e.g., for complex or expensive operations):
$factory->define(Order::class, function () {
return [
'user_id' => $this->faker->randomElement(User::all()->pluck('id')),
'total' => $this->faker->randomFloat(2, 50, 5000),
'created_at' => $this->faker->dateTimeThisYear,
];
});
Stateful Factories: Chain factories with stateful data:
$factory->state(User::class, function ($faker) {
return ['role' => 'admin'];
});
$factory->define(User::class, function () {
return [
'name' => $this->faker->name,
'email' => $this->faker->unique()->safeEmail,
'role' => $this->state('role'),
];
});
AfterCreating Hooks: Use Faker to generate dynamic data post-creation:
$factory->afterCreating(User::class, function ($user) {
$user->apiToken = $this->faker->uuid;
$user->save();
});
Laravel Integration:
Pair with Laravel’s DatabaseFactory for seamless Eloquent model testing:
$factory->defineAs(User::class, new UserFactory($faker));
Define UserFactory as a custom factory class extending League\FactoryMuffin\Factory.
Custom Faker Providers:
Extend Faker’s providers (e.g., Address, Lorem) and use them in factories:
$factory->define(Address::class, function () {
return [
'street' => $this->faker->address->streetName,
'city' => $this->faker->address->city,
];
});
Seeding with Faker: Use factories to seed your database with realistic test data:
$factory->createMany(User::class, 10); // 10 users with unique Faker data
Faker Instance Scope:
define, state, etc.) shares the same $this->faker instance.$faker = Faker\Factory::create();
$factory->define(User::class, function () use ($faker) {
return ['name' => $faker->name];
});
Unique Constraints:
unique() may fail if the dataset is large or constraints are tight (e.g., unique()->email with 10,000 users).unique()->safeEmail or implement custom uniqueness logic:
$factory->afterCreating(User::class, function ($user) {
while (User::where('email', $user->email)->exists()) {
$user->email = $this->faker->unique()->safeEmail;
}
});
PHP Version Quirks:
string vs. mixed).uuid() requires Faker ^1.9).Lazy Evaluation Pitfalls:
create() or make()).dd($this->faker->method()) inside factory definitions to inspect generated values.Inspect Faker Output: Temporarily log Faker’s output to debug:
$factory->define(User::class, function () {
$name = $this->faker->name;
\Log::debug("Generated name: {$name}");
return ['name' => $name];
});
Reset Faker Seed: Force a new seed for reproducible tests:
$this->faker->seed(1234);
Custom Faker Providers: If using custom providers, ensure they’re registered with Faker:
$faker = Faker\Factory::create();
$faker->addProvider(new CustomProvider($faker));
Custom FactoryMuffinFaker:
Extend League\FactoryMuffinFaker\FactoryMuffinFaker to add domain-specific methods:
class CustomFactoryMuffinFaker extends FactoryMuffinFaker {
public function slug() {
return $this->faker->unique()->slug;
}
}
Dynamic Factory Definitions: Use Faker to generate factory definitions dynamically:
$factory->define(dynamic_class(), function () {
return ['field' => $this->faker->word];
});
Integration with Laravel Mixins:
Combine with Laravel’s createFaker() helper for concise syntax:
$factory->define(User::class, function () {
return [
'name' => createFaker()->name,
];
});
$faker = Faker\Factory::create();
$factory->define(User::class, function () use ($faker) {
return ['name' => $faker->name];
});
createMany() for bulk operations to minimize database writes:
$factory->createMany(User::class, 1000);
How can I help you explore Laravel packages today?