PHPackages                             christophrumpel/laravel-factories-reloaded - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Testing &amp; Quality](/categories/testing)
4. /
5. christophrumpel/laravel-factories-reloaded

ActiveLibrary[Testing &amp; Quality](/categories/testing)

christophrumpel/laravel-factories-reloaded
==========================================

This package sits on top of Laravel factories and provides you with dedicated factory classes for every model.

v3.0.0(4y ago)38147.8k19[2 issues](https://github.com/christophrumpel/laravel-factories-reloaded/issues)MITPHPPHP ^8.0CI failing

Since Feb 3Pushed 4y ago12 watchersCompare

[ Source](https://github.com/christophrumpel/laravel-factories-reloaded)[ Packagist](https://packagist.org/packages/christophrumpel/laravel-factories-reloaded)[ Docs](https://github.com/christophrumpel/laravel-factories-reloaded)[ RSS](/packages/christophrumpel-laravel-factories-reloaded/feed)WikiDiscussions master Synced 3w ago

READMEChangelog (10)Dependencies (9)Versions (48)Used By (0)

Laravel Factories Reloaded 🏭
============================

[](#laravel-factories-reloaded-)

[![Latest Version on Packagist v1](https://camo.githubusercontent.com/6a4837e25c8499bca14ec157694a5aa1d3dc8f88ced4c3213d03d92913c7c668/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6368726973746f706872756d70656c2f6c61726176656c2d666163746f726965732d72656c6f616465642e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/christophrumpel/laravel-factories-reloaded)[![Total Downloads](https://camo.githubusercontent.com/3bb0b33884fc53b8115d30c15150abee1de2818c27e4e3a94802ce0aa38eaa63/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6368726973746f706872756d70656c2f6c61726176656c2d666163746f726965732d72656c6f616465642e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/christophrumpel/laravel-factories-reloaded)[![MIT Licensed](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](LICENSE.md)

This package generates `class-based` model factories, which you can use instead of the ones provided by Laravel.

[![Screenshot of the command](https://camo.githubusercontent.com/9ddffb40d25487e733f3a3a6dfeff632fdd6be28c0df5aa826155d7b8869dde2/687474703a2f2f73637265656e73686f74732e6e6f6d6f7265656e636f72652e636f6d2f6c66725f736f6369616c5f696d6167655f66756c6c2e706e67)](https://camo.githubusercontent.com/9ddffb40d25487e733f3a3a6dfeff632fdd6be28c0df5aa826155d7b8869dde2/687474703a2f2f73637265656e73686f74732e6e6f6d6f7265656e636f72652e636f6d2f6c66725f736f6369616c5f696d6167655f66756c6c2e706e67)

Laravel 8 Support
-----------------

[](#laravel-8-support)

The new version v3 now supports Laravel 8 and PHP 8+. Since L8 changed their own implementation of factories a lot, this new v2 version ONLY works with Laravel 8. If you are not using L8 yet, use the latest 1.\* version of this package, if you need PHP 7 support, use the latest 2.\* version.

Benefits
--------

[](#benefits)

- use the **features you already love from Laravel factories** (`create`, `make`, `times`, `states`)
- **automatically create** new class factories for specific or `All` your models
- **automatically import** defined `default data` and `states` from your Laravel factories
- and many more...

📺 I've recorded some [videos](https://www.youtube.com/playlist?list=PLk9WlAgeZoTep60sHw8tMhXVpLuH3DV0Z) to give you an overview of the features.

> ⚠️ **Note**: Interested in WHY you need class-based factories? Read [here](#why-class-based-factories).

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require --dev christophrumpel/laravel-factories-reloaded
```

To publish the config file run:

```
php artisan vendor:publish --provider="Christophrumpel\LaravelFactoriesReloaded\LaravelFactoriesReloadedServiceProvider"
```

It will provide the package's config file where you can define `multiple paths of your models`, the `path of the newly generated factories`, the `namespace of your old Laravel factories`, as well as where your `old Laravel factories` are located.

Configuration
-------------

[](#configuration)

### Laravel Factories Namespace

[](#laravel-factories-namespace)

Factories are namespaced since Laravel 8, and the default factories namespace is `Database\Factories`. If your laravel factories namespace is `Database\Factories\ClassFactories`, you can customize it at the config file as below:

```
'vanilla_factories_namespace' => 'Database\Factories\ClassFactories',
```

It will resolve your old laravel factory class as `Database\Factories\ClassFactories\UserFactory`, instead of `Database\Factories\UserFactory`.

Usage
-----

[](#usage)

### Generate Factories

[](#generate-factories)

First, you need to create a new factory class for one of your models. This is done via a newly provided command called `make:factory-reloaded`.

```
php artisan make:factory-reloaded
```

You can pick one of the found models or create factories for `all` of them.

#### Command Options

[](#command-options)

If you want to define options through the command itself, you can do that as well:

```
php artisan make:factory-reloaded --models_path="app/Models"  --factories_path="tests/ClassFactories" --factories_namespace="Tests\ClassFactories"
```

Currently, you can only define one location for your models this way.

### Define Default Model Data

[](#define-default-model-data)

Similar to Laravel factories, you can define default data for your model instances. Inside your new factories, there is a `getDefaults` method defined for that. The `Faker` helper to create dummy data is available as well.

```
public function getDefaults(Faker $faker): array
{
    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'email_verified_at' => now(),
        'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi',
        'remember_token' => Str::random(10),
        'active' => false,
    ];
}
```

### Use New Factories

[](#use-new-factories)

Let's say you have created a new user factory. You can now start using it and create a new user instance. Similar to Laravel factories, the `create` method will persist in a new model.

```
$user = UserFactory::new()->create();
```

If you like to get an instance that is not persisted yet, you can choose the `make` method.

```
$user = UserFactory::new()->make();
```

To create `multiple` instances, you chain the `times()` method before the `create` or `make` method.

```
$users = UserFactory::new()
    ->times(4)
    ->create();
```

### States

[](#states)

You may have defined states in your old Laravel factories.

```
$factory->state(User::class, 'active', function () {
    return [
        'active' => true,
    ];
});
```

While creating a new class factory, you will be asked if you like those states to be imported to your new factories. If you agree, you can immediately use them. The state `active` is now a method on your `UserFactory`.

```
$user = UserFactory::new()
    ->active()
    ->create();
```

### Relations

[](#relations)

Often you will need to create a new model instance with related models. This is now pretty simple by using the `with` method:

```
$user = UserFactory::new()
    ->with(Recipe::class, 'recipes', 3)
    ->create();
```

Here were are getting a user instance that has three related recipes attached. The second argument here defines the relationship name.

> ⚠️ **Note**: For this to work, you need to have a new RecipeFactory already created.

You can also define extras for the related models when using related model factories directly.

```
$user = UserFactory::new()
    ->withFactory(RecipeFactory::new()->withCustomName(), 'recipes', 3)
    ->create();
```

You can create many related models instances by chaining `with`s.

```
$recipe = RecipeFactory::new()
    ->with(Group::class, 'group')
    ->with(Ingredient::class, 'ingredients')
    ->with(Ingredient::class, 'ingredients', 3)
    ->create();
```

Here we are getting a recipe that has a group and four ingredients.

> ⚠️ **Note**: Up to the version 1.0.8, only the last `with` relation is built.

In Laravel factories, you could also define a related model in your default data like:

```
$factory->define(Ingredient::class, function (Faker $faker) {
    return [
        'name' => $faker->name,
        'recipe_id' => factory(Recipe::class),
    ];
});
```

This can also be achieved in our new factory classes.

```
public function getDefaults(Faker $faker): array
{
    return [
        'name' => $faker->name,
        'recipe_id' => factory(Recipe::class),
    ];
}
```

Or even better through an instance of a new factory class.

```
public function getDefaults(Faker $faker): array
{
    return [
        'name' => $faker->name,
        'recipe_id' => RecipeFactory::new(),
    ];
}
```

> ⚠️ **Note**: I wouldn't recommend any of these options because you do not see that additional models are persisted in your tests. Please use the given "with" method create a dedicated method for creating a relation yourself.

### Callbacks

[](#callbacks)

In Laravel, you are able to define factory `callbacks` for `afterCreating` and `afterMaking`. You can do something similar also with factory classes. Since both the `make` and `create` method are inside your factory class, you are free to add code there:

```
public function create(array $extra = []): Group
{
    return $this->build($extra);
}

public function make(array $extra = []): Group
{
    return $this->build($extra, 'make');
}
```

It depends on what you want to achive, but personally I would add a method to your factory which you call from within your test. This way it is more obvious what is happening.

### Immutability

[](#immutability)

You might have noticed that when this package imports a `state` for you, it will clone the factory before returning.

```
public function active(): UserFactory
{
    return tap(clone $this)->overwriteDefaults([
        'active' => true,
    ]);
}
```

This is recommended for all methods which you will use to setup your test model. If you wouldn't clone the factory, you will always modify the factory itself. This could lead into problems when you use the same factory again.

To make a whole factory immutable by default, set the `$immutable` property to `true`. That way, every state change will automatically return a cloned instance.

```
class UserFactory
{
    protected string $modelClass = User::class;
    protected bool $immutable = true;

    // ...

    public function active(): UserFactory
    {
        return $this->overwriteDefaults([
            'active' => true,
        ]);
    }
}
```

In some context, you might want to use a standard factory as immutable. This can be done with the `immutable` method.

```
$factory = UserFactory::new()
    ->immutable();

$activeUser = $factory
    ->active()
    ->create();

$inactiveUser = $factory->create();
```

> **Note**: `with` and `withFactory` methods are always immutable.

### What Else

[](#what-else)

The best thing about those new factory classes is that you `own` them. You can create as many methods or properties as you like to help you create those specific instances that you need. Here is how a more complex factory call could look like:

```
UserFactory::new()
    ->active()
    ->onSubscriptionPlan(SubscriptionPlan::paid)
    ->withRecipesAndIngredients()
    ->times(10)
    ->create();
```

Using such a factory call will help your tests to stay clean and give everyone a good overview of what is happening here.

Why Class-Based Factories?
--------------------------

[](#why-class-based-factories)

- They give you much more flexibility on how to create your model instances.
- They make your tests much cleaner because you can hide complex preparations inside the class.
- They provide IDE auto-completion which you do not get have with Laravel factories.

Testing
-------

[](#testing)

```
composer test
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information about what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security
--------

[](#security)

If you discover any security-related issues, please email  instead of using the issue tracker.

Credits
-------

[](#credits)

- [Christoph Rumpel](https://github.com/christophrumpel)
- [All Contributors](../../contributors)

Some of the implementations are inspired by [Brent's article](https://stitcher.io/blog/laravel-beyond-crud-09-test-factories) about how they deal with factories at Spatie.

And a big thanks goes out to [Adrian](https://github.com/nuernbergerA) who helped me a lot with refactoring this package.

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

45

—

FairBetter than 91% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity44

Moderate usage in the ecosystem

Community26

Small or concentrated contributor base

Maturity75

Established project with proven stability

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~23 days

Recently: every ~132 days

Total

35

Last Release

1546d ago

Major Versions

v0.0.16 → v1.0.02020-04-20

v1.3.0 → v2.02020-10-23

v2.2.0 → v3.0.02022-04-04

PHP version history (2 changes)v0.0.1PHP ^7.4

v3.0.0PHP ^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/f28b771a37a269a91595451004ddb985e9469795957868e0ff3626e9a6c43533?d=identicon)[christophrumpel](/maintainers/christophrumpel)

---

Top Contributors

[![christophrumpel](https://avatars.githubusercontent.com/u/1394539?v=4)](https://github.com/christophrumpel "christophrumpel (69 commits)")[![nuernbergerA](https://avatars.githubusercontent.com/u/13331388?v=4)](https://github.com/nuernbergerA "nuernbergerA (41 commits)")[![BertvanHoekelen](https://avatars.githubusercontent.com/u/7521173?v=4)](https://github.com/BertvanHoekelen "BertvanHoekelen (7 commits)")[![simonschaufi](https://avatars.githubusercontent.com/u/941794?v=4)](https://github.com/simonschaufi "simonschaufi (6 commits)")[![shaffe-fr](https://avatars.githubusercontent.com/u/3834222?v=4)](https://github.com/shaffe-fr "shaffe-fr (6 commits)")[![GuidoHendriks](https://avatars.githubusercontent.com/u/5393965?v=4)](https://github.com/GuidoHendriks "GuidoHendriks (6 commits)")[![szepeviktor](https://avatars.githubusercontent.com/u/952007?v=4)](https://github.com/szepeviktor "szepeviktor (5 commits)")[![dbushy727](https://avatars.githubusercontent.com/u/5914258?v=4)](https://github.com/dbushy727 "dbushy727 (4 commits)")[![code-distortion](https://avatars.githubusercontent.com/u/56794290?v=4)](https://github.com/code-distortion "code-distortion (4 commits)")[![JoshMoreno](https://avatars.githubusercontent.com/u/22627952?v=4)](https://github.com/JoshMoreno "JoshMoreno (4 commits)")[![EranNL](https://avatars.githubusercontent.com/u/10157169?v=4)](https://github.com/EranNL "EranNL (3 commits)")[![edgrosvenor](https://avatars.githubusercontent.com/u/1053395?v=4)](https://github.com/edgrosvenor "edgrosvenor (3 commits)")[![Lloople](https://avatars.githubusercontent.com/u/5665466?v=4)](https://github.com/Lloople "Lloople (2 commits)")[![barnabaskecskes](https://avatars.githubusercontent.com/u/3535449?v=4)](https://github.com/barnabaskecskes "barnabaskecskes (2 commits)")[![thijsvdanker](https://avatars.githubusercontent.com/u/429548?v=4)](https://github.com/thijsvdanker "thijsvdanker (1 commits)")[![deligoez](https://avatars.githubusercontent.com/u/3030815?v=4)](https://github.com/deligoez "deligoez (1 commits)")[![devmsh](https://avatars.githubusercontent.com/u/9499808?v=4)](https://github.com/devmsh "devmsh (1 commits)")[![irakan](https://avatars.githubusercontent.com/u/61325228?v=4)](https://github.com/irakan "irakan (1 commits)")[![MohammedAlkutrani](https://avatars.githubusercontent.com/u/24508555?v=4)](https://github.com/MohammedAlkutrani "MohammedAlkutrani (1 commits)")[![pkboom](https://avatars.githubusercontent.com/u/13960169?v=4)](https://github.com/pkboom "pkboom (1 commits)")

---

Tags

laravellaravel-factorytestingchristophrumpellaravel-factories-reloaded

###  Code Quality

TestsPHPUnit

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/christophrumpel-laravel-factories-reloaded/health.svg)

```
[![Health](https://phpackages.com/badges/christophrumpel-laravel-factories-reloaded/health.svg)](https://phpackages.com/packages/christophrumpel-laravel-factories-reloaded)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.1M337](/packages/psalm-plugin-laravel)[christophrumpel/missing-livewire-assertions

This package adds missing livewire test assertions.

150386.1k12](/packages/christophrumpel-missing-livewire-assertions)[laravel/surveyor

Static analysis tool for Laravel applications.

8690.3k12](/packages/laravel-surveyor)[api-platform/laravel

API Platform support for Laravel

59156.3k11](/packages/api-platform-laravel)[zidbih/laravel-deadlock

Make temporary Laravel workarounds expire and fail CI when ignored.

984.0k](/packages/zidbih-laravel-deadlock)[tomshaw/electricgrid

A feature-rich Livewire package designed for projects that require dynamic, interactive data tables.

119.2k](/packages/tomshaw-electricgrid)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
