PHPackages                             morrislaptop/popo-factory - 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. morrislaptop/popo-factory

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

morrislaptop/popo-factory
=========================

Making it easy to mock your POPO's

v0.4.0(3y ago)9157.5k4MITPHPPHP ^8.0

Since Jan 24Pushed 2y ago1 watchersCompare

[ Source](https://github.com/morrislaptop/popo-factory)[ Packagist](https://packagist.org/packages/morrislaptop/popo-factory)[ Docs](https://github.com/morrislaptop/popo-factory)[ RSS](/packages/morrislaptop-popo-factory/feed)WikiDiscussions master Synced yesterday

READMEChangelog (6)Dependencies (10)Versions (7)Used By (0)

Making it easy to mock your POPO's / Value Objects
==================================================

[](#making-it-easy-to-mock-your-popos--value-objects)

[![Latest Version on Packagist](https://camo.githubusercontent.com/358c4e04f655b3dd6a5dbf51d84c7191be0442206bda8944de8addeb347d3e33/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6d6f727269736c6170746f702f706f706f2d666163746f72792e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/morrislaptop/popo-factory)[![GitHub Tests Action Status](https://camo.githubusercontent.com/56438f7648a504bfc39efb9869f46319fbec3ab99244ca49ef949efc716df048/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f776f726b666c6f772f7374617475732f6d6f727269736c6170746f702f706f706f2d666163746f72792f54657374733f6c6162656c3d7465737473)](https://github.com/morrislaptop/popo-factory/actions?query=workflow%3ATests+branch%3Amaster)[![Total Downloads](https://camo.githubusercontent.com/edc46e2464786ac8ae726b8b9de47b39b9b7982d39911223aa94a5195e99edfe/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6d6f727269736c6170746f702f706f706f2d666163746f72792e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/morrislaptop/popo-factory)

This package supports mocking POPOs or Value Objects, it inspects your class properties and populates them with random data generated by Faker. You can create class-based mock factories to have a fluent interface to mock POPOs for different states.

This is a fork of [Data Transfer Object Factory](https://github.com/anteris-dev/data-transfer-object-factory).

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

[](#installation)

You can install the package via composer:

```
composer require morrislaptop/popo-factory --dev
```

Usage
-----

[](#usage)

```
use Morrislaptop\PopoFactory\PopoFactory;

class PersonData
{
    public function __construct(
        public $firstName,
        public string $lastName,
        public string $email,
        public string $homeAddress,
        public ?string $companyName,
        public string $workAddress,
        public Carbon $dob,
        public PersonData $spouse,
    ) {
    }
}

PopoFactory::new(PersonData::class)->make();
```

Which creates an object that looks like this:

```
{
  "firstName": "Jada",
  "lastName": "Bechtelar",
  "email": "edmond.mcglynn@example.org",
  "homeAddress": "640 Feest Landing\nBernierburgh, PA 99277",
  "companyName": "Ratke Inc",
  "workAddress": "75107 Konopelski Radial\nRutherfordport, AK 22994",
  "dob": "2021-01-26T11:04:31.393991Z",
  "spouse": {
    "firstName": "Leola",
    "lastName": "Koss",
    "email": "friedrich41@example.org",
    "homeAddress": "852 Fabian Mills\nNorth Ward, NM 54459",
    "companyName": "Fahey and Sons",
    "workAddress": "671 Creola Prairie Apt. 663\nNorth Gretchenview, OR 75622-4176"
  }
}
```

The `new` method returns an instance of `Morrislaptop\PopoFactory\PopoFactory` which provides the following methods.

- `count()` - *Allows you to specify how many POPOs to be generated. They will be returned in an array.*
- `make()` - *Called when you are ready to generate the POPO(s). Returns the generated object(s).*
- `random()` - *Generates a random number of POPOs*
- `sequence()` - *Alternates a specific state. (See below)*
- `state()` - *Manually sets properties based on the array of values passed.*

Examples of these methods can be found below.

```
// Creates two DTOs in an array
PopoFactory::new(PersonData::class)->count(2)->make();

// Sets the first name of every person to "Jim"
PopoFactory::new(PersonData::class)
    ->random()
    ->state([
        'firstName' => 'Jim',
    ])
    ->make();

// Alternates the names of each person between "Jim" and "Susie"
PopoFactory::new(PersonData::class)
    ->random()
    ->sequence(
        [ 'firstName' => 'Jim' ],
        [ 'firstName' => 'Susie' ]
    )
    ->make();
```

Creating Class Based Factories
------------------------------

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

It's useful to define specific factories for particular objects, which can easily be done by extending the `PopoFactory` class.

My specifying a typehint for the `make()` method you will also get typehints in your IDE for your mocked object.

```
/**
 * @method PersonData make
 */
class PersonDataFactory extends PopoFactory
{
    public static function factory(): static
    {
        return static::new(PersonData::class)->state([
            'firstName' => 'Craig'
        ]);
    }

    public function gotNoJob() {
        return $this->state([
            'companyName' => null,
        ]);
    }

    public function worksAtHome() {
        return $this->state(function ($attributes) {
            return [
                'workAddress' => $attributes['homeAddress']
            ];
        });
    }
}
```

Then using it in tests like so:

```
$person = PersonDataFactory::factory()
            ->gotNoJob()
            ->worksAtHome()
            ->make();
```

Extending
---------

[](#extending)

You can easily extend the factory to support other data types. You can do this through the static `registerProvider()` method on the `PropertyFactory` class. This method takes two arguments. The first should be the FQDN of the class you are providing (e.g. `Carbon\Carbon`) OR the built-in type (e.g. `string`). The second should be a callback that returns the generated value. This callback is passed two properties when called to assist in generating the value. The first is an instance of `Anteris\FakerMap\FakerMap` which can be used to help generate fake data. The second is an instance of `ReflectionProperty` which contains information about the property being generated.

For example, to support Carbon:

```
use Morrislaptop\PopoFactory\PropertyFactory;

use Anteris\FakerMap\FakerMap;

PropertyFactory::registerProvider('Carbon\Carbon', fn(FakerMap $fakerMap) => Carbon::parse(
    $fakerMap->closest('dateTime')->fake()
));
```

Plug
----

[](#plug)

Want an easy way to persist your POPOs in Laravel? Check out [laravel-popo-caster](https://github.com/morrislaptop/laravel-popo-caster)

Testing
-------

[](#testing)

```
composer test
```

Changelog
---------

[](#changelog)

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

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

[](#contributing)

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

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [Craig Morris](https://github.com/morrislaptop)
- [All Contributors](../../contributors)

License
-------

[](#license)

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

###  Health Score

32

—

LowBetter than 72% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity32

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 87.5% of commits — single point of failure

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 ~106 days

Recently: every ~133 days

Total

6

Last Release

1400d ago

PHP version history (2 changes)v0.1.0PHP ^7.4|^8.0

v0.2.1PHP ^8.0

### Community

Maintainers

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

---

Top Contributors

[![morrislaptop](https://avatars.githubusercontent.com/u/67807?v=4)](https://github.com/morrislaptop "morrislaptop (28 commits)")[![tigitz](https://avatars.githubusercontent.com/u/1524501?v=4)](https://github.com/tigitz "tigitz (2 commits)")[![erikgaal](https://avatars.githubusercontent.com/u/1234268?v=4)](https://github.com/erikgaal "erikgaal (1 commits)")[![lukio3](https://avatars.githubusercontent.com/u/21043078?v=4)](https://github.com/lukio3 "lukio3 (1 commits)")

---

Tags

fakerpopovaluemorrislaptoppopo-factory

###  Code Quality

TestsPHPUnit

Static AnalysisPsalm

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/morrislaptop-popo-factory/health.svg)

```
[![Health](https://phpackages.com/badges/morrislaptop-popo-factory/health.svg)](https://phpackages.com/packages/morrislaptop-popo-factory)
```

###  Alternatives

[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.4k5.6M651](/packages/sylius-sylius)[api-platform/core

Build a fully-featured hypermedia or GraphQL API in minutes!

2.6k48.1M236](/packages/api-platform-core)[shopware/platform

The Shopware e-commerce core

3.3k1.5M3](/packages/shopware-platform)[zenstruck/foundry

A model factory library for creating expressive, auto-completable, on-demand dev/test fixtures with Symfony and Doctrine.

78311.9M97](/packages/zenstruck-foundry)[api-platform/symfony

Symfony API Platform integration

323.2M67](/packages/api-platform-symfony)[prestashop/prestashop

PrestaShop is an Open Source e-commerce platform, committed to providing the best shopping cart experience for both merchants and customers.

9.0k15.4k](/packages/prestashop-prestashop)

PHPackages © 2026

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