PHPackages                             er1z/fakemock - 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. er1z/fakemock

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

er1z/fakemock
=============

A library to provide mocking abilities for annotated class properties

0.3.1(7y ago)61.8k1[5 issues](https://github.com/er1z/fakemock/issues)1mitPHPPHP ^7.1

Since Nov 13Pushed 7y ago1 watchersCompare

[ Source](https://github.com/er1z/fakemock)[ Packagist](https://packagist.org/packages/er1z/fakemock)[ RSS](/packages/er1z-fakemock/feed)WikiDiscussions master Synced 2mo ago

READMEChangelogDependencies (7)Versions (8)Used By (1)

Fakemock
--------

[](#fakemock)

[![Build Status](https://camo.githubusercontent.com/d6cb039201e59df64314e6b3323425a1e454711452aa5e6804f09be7d39eee74/68747470733a2f2f7472617669732d63692e6f72672f6572317a2f66616b656d6f636b2e7376673f6272616e63683d646576)](https://travis-ci.org/er1z/fakemock) [![Scrutinizer Code Quality](https://camo.githubusercontent.com/516acd546ce3daa486ee1813781c6c77ebdf581f4b0c6a60ffa3425d0a39c8c0/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6572317a2f66616b656d6f636b2f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/er1z/fakemock/?branch=master) [![Code Coverage](https://camo.githubusercontent.com/d8a7f348114f66b703b8fc62aa324e79a0d81abcbf7fcaceaa899cdb995ed60e/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6572317a2f66616b656d6f636b2f6261646765732f636f7665726167652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/er1z/fakemock/?branch=master)

[Faker](https://github.com/fzaninotto/Faker) is an amazing tool for mocking things but has a one drawback — you have to do much of work in order to map all things you need. Especially when you are working with DTOs/Entities and they already have some assertions configured — the dev has to create very own rules from scratch.

This library solves that problem. I have introduced a `FakeMock` library that takes care of filling up as many objects as you need.

ToC

- [Install](#install)
- [Quick example](#quick-example)
- [Configuration](#configuration)
- [Populating multiple objects](#populating-multiple-objects)
- [Groups](#groups)
- [phpDoc](#phpdoc)
- [Supported DTOs](#supported-dtos)
- [Asserts](#asserts)
- [Supported asserts](#supported-asserts)
- [Internal architecture](#internal-architecture)
- [Advanced concepts](#advanced-concepts)

Install
-------

[](#install)

Install the library:

```
composer require er1z/fakemock
```

Quick example
-------------

[](#quick-example)

We assume all the autoloaders stuff is configured so create (or re-use) your DTO:

```
use Er1z\FakeMock\Annotations\FakeMock as FakeMock;
use Er1z\FakeMock\Annotations\FakeMockField as FakeMockField;

/**
 * @FakeMock()
 */
class MyDto {

    /**
     * @FakeMockField()
     */
    public $username;

}
```

Now — fill up above with some random data:

```
$fakemock = new Er1z\FakeMock\FakeMock();

$dto = new MyDto();
$fakemock->fill($dto);

echo $dto->username;   // mr.handsome
```

What's happened — [name guesser](https://github.com/fzaninotto/Faker/blob/master/src/Faker/Guesser/Name.php) is used here so it assumed that `$username` may contain your user's login. But guessing not always would fit your needs. It's possible to specify *any* Faker's method to fill it with random data:

```
/**
 * @FakeMockField("name")
 */
public $username;
```

and we end up with generated some random first and last name.

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

[](#configuration)

Most part of behavior is controlled via annotations. We can specify two types of configuration: global (object-scope) and local (property-scope). All available properties for global scope:

typenamedefault valuedescription`bool``satisfyAssertsConditions``true`enables/disables asserts decorator (see: [supported asserts](#supported-asserts))`bool``useAsserts``true`should FakeMock use assertions to generate data?`array``classMappings``[]`specifies a dictionary of `SomeClass=>FQCN` for mapping interfaces within this field`string`|`null``locale``null`locale to use with FakerLocal scope:

typenamedefault valuedescription`null`|`array``arguments``null`an array of arguments for Faker method`null`|`string``faker``null`specify desired faker method. Set to null if you want to generator chain do it's best on guessing`null`|`array|string``groups``null`validation groups this rule for this rule is being processed.`null`|`string``regex``null`a regular expression to generate random data against`null`|`bool``satisfyAssertConditions``null`turns off or on assertion decorator — `null` inherits value from global configuration`null`|`bool``useAsserts``null`should FakeMock use validation rules to generate? If `null`, value is inherited from global configuration`null`|`mixed``value``null`literal value on field. Stops guessing`null`|`string``mapToClass``null`FQCN of class the object should be instantiated as`string`|`null``locale``null`locale to use with FakerLocal scope configuration constructor has a possibility to create an annotation from string-argument which is populated to `faker` key.

Populating multiple objects
---------------------------

[](#populating-multiple-objects)

Developers are lazy so am I — you have to take care of things you really need to. So let's populate a few objects:

```
$fakemock = new FakeMock();

$results = [];

for( $a=0; $afill(MyDto::class);
}
```

That's all. They all are fresh instances so don't be concerned any references.

Groups
------

[](#groups)

Sometimes it's needed to populate objects conditionally. Let's try with populating every 3rd generated object. First, declare a group of field:

```
use Er1z\FakeMock\Annotations\FakeMock as FakeMock;
use Er1z\FakeMock\Annotations\FakeMockField as FakeMockField;

/**
 * @FakeMock()
 */
class GroupedDto {

    /**
     * @FakeMockField(groups={"first"})
     */
    public $field;

}
```

Generate:

```
$fakemock = new FakeMock();

$results = [];

for( $a=0; $afill(MyDto::class, $a%3==0 ?? 'first');
}
```

Now, check your results. This behavior is similar to Symfony's [validation groups](https://symfony.com/doc/current/form/validation_groups.html).

phpDoc
------

[](#phpdoc)

If no guess is possible and you haven't mapped any particular Faker's type, FakeMock tries to guess type according to phpDoc variable type:

```
use Er1z\FakeMock\Annotations\FakeMock as FakeMock;
use Er1z\FakeMock\Annotations\FakeMockField as FakeMockField;

/**
 * @FakeMock()
 */
class DocDTO {

    /**
     * @var float
     * @FakeMockField()
     */
    public $field;

}
```

```
$f = new FakeMock();
$obj = new DocDTO();

$data = $f->fill($obj);

var_dump($data->field); // eg. 1.24422
```

Supported DTOs
--------------

[](#supported-dtos)

FakeMock relies on [PropertyAccess](https://github.com/symfony/property-access) component so different kinds of DTOs are supported, even Doctrine entities. You can leave an object with exposed public fields but also encapsulate data via setters and getters:

```
use Er1z\FakeMock\Annotations\FakeMock as FakeMock;
use Er1z\FakeMock\Annotations\FakeMockField as FakeMockField;

/**
 * @FakeMock()
 */
class EncapsulatedDTO
{
    /**
     * @FakeMockField();
     */
    protected $field;

    public function getField()
    {
        return $this->field;
    }

    public function setField($field)
    {
        $this->field = $field;
    }

}
```

And this will just work.

Asserts
-------

[](#asserts)

If your project is using [Symfony's validate](https://github.com/symfony/validate) component, it's possible to utilize validation rules to tell the FakeMock how generate fields contents. For example:

```
use Er1z\FakeMock\Annotations\FakeMock as FakeMock;
use Er1z\FakeMock\Annotations\FakeMockField as FakeMockField;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @FakeMock()
 */
class ValidatedDTO {

    /**
     * @FakeMockField()
     * @Assert\Email()
     */
    public $email;

}
```

and calling `fill` method against this object will produce fake e-mail address on `$email` field.

Supported asserts
-----------------

[](#supported-asserts)

Generators:

AssertSupport statusDescriptionAllunsupportedBicsupportedSwift BIC codeBlanksupportednullifies fieldCallbackunsupportedCardSchemepartial-supportgenerates a valid credit card number — currently only `visa`, `mastercard` and `amex` are supportedChoicesupportedreturns a value based on choices — supported are both single and multipleCollectionunsupportedCountunsupportedCountrysupportedgenerates a country codeCurrencysupportedcurrency codeDatepartial-supportedgenerates a date, currently according to `DATE_ATOM` formatDateTimepartial-supportedgenerates a date with time, currently: `ISO` formatEmailsupportedgenerates a valid e-mail addressExpressionunsupportedFileunsupportedIbansupportedgenerates an IBAN account numberImagesupportedgenerates a `SplFileObject` with image of specified dimensionsIpsupportedgenerates an IPv4/v6 addressIsbnsupportedgenerates an ISBNIsFalsesupportedreturns false to fieldIsNullsupportednullifies fieldIssnpartial-supportonly single hard-coded ISSN numberIsTruesupportedreturns true to fieldLanguagesupportedgenerates a string with language codeLocalesupportedgenerates a locale stringLuhnpartial-supportgenerates a credit card number for LUHN algorithm validationNotBlanksupportedchecks whether field is not emptyNotNullsupportedfield is not nullRegexsupportedgenerates a string that matches patternTimepartial-supportedgenerates a time with `H:i:s` formatTypeunsupportedUniqueEntityunsupportedUrlsupportedgenerates a valid URLUserPasswordunsupportedUuidsupportedgenerates an UUIDValidunsupportedDecorators/conditionals:

AssertsupportdescriptionEqualTosupportedequalizes value to specified literal or `propertyPath` field valueGreaterThansupportedchecks if generated value matches lower boundary (not inclusive)GreaterThanOrEqualsupportedchecks if generated value matches lower boundary (inclusive)IdenticalTopartial-supportsimilar to `EqualTo` but also checks type, currently: alias to `EqualTo`Lengthsupportedgenerates a string between min-max length boundaryLessThansupportedchecks if generated value matches upper boundary (not inclusive)LessThanOrEqualsupportedchecks if generated value matches upper boundary (inclusive)NotEqualTosupportedmakes sure that field's value is different from literal or `propertyPath` field valueNotIdenticalTopartial-supportsimilar to `NotEqualTo` but also checks type, currently: alias to `NotEqualTo`Rangesupportedgenerates a number within specified boundariesFakeMock is smart enough to guess what you want to get — asserts are also decorated against specified phpDoc type, for example if you specify `LessThan` constraint and `@var float`, you get float value and so on. This feature is useful when you need a `DateTimeInterface` in string:

```
/**
 * @FakeMock()
 * @Assert\DateTime()
 * @var string
 */
```

Internal architecture
---------------------

[](#internal-architecture)

FakeMock is a library with fair amount of tests so you don't need to bother if you want to make a contribution and concerned your code will mess up something.

Modular architecture allows to enhance and extend functionality. The main entrypoint is a `FakeMock` class which needs three elements:

- `Metadata\FactoryInterface` — builds some information on fields metadata, eg. if it should be processed, what rules are specified and so on,
- `GeneratorChainInterface` — maintains a list of field-data generators,
- `DecoratorChainInterface` — holds a list of decorators which can be used to modify generated value according to various rules, eg. convert `DateTimeInterface` to string.

Almost all modules could be overrided thanks to passing the dependencies mostly by interfaces or constructor arguments. So feel free to play with all components.

Generating of data step-by-step:

1. Create a `FakeMock` instance with specified object/FQCN to generate (if FQCN, instantiate silently),
2. Pass object to `Metadata\FactoryInterface` in order to get main object configuration,
3. If object is configured, iterate over object properties, create `FieldMetadata` merging some configuration variables with object configuration and check if group is specified and if it should be processed,
4. Tell `GeneratorChainInterface` to `getValueForField`. Available adapters are executed one-by-one until one of them returns non-null value,
5. Run `DecoratorChainInterface` with `getDecoratedValue` — mostly, they are all ran one-by-one except currently processed returns `false` which breaks the chain,
6. Set generated value by accessor.

Default generator chain:

1. `TypedGenerator` — handles two cases: `value` or `regex`. Nothing less, nothing more,
2. `RecursiveGenerator` — if variable class has FQCN specified in phpDoc, it's processed unless `recursive` field flag is set to `false`,
3. If package `symfony/validator` is installed and available, `AssertGenerator` is being checked against,
4. `FakerGenerator` — provides methods for generating specified Faker's generator or guess field content by `NameGuesser`,
5. `PhpDocGenerator` — generates data according to the property type,
6. `LastResortGenerator` — if everything above fails, generates simple name as string.

Default decorators chain:

1. `AssertDecorator` — restrict values to validation rules — its behavior is controlled by `satisfyAssertsConditions` field configuration,
2. `PhpDocDecorator` — converts values types.

Advanced Concepts
-----------------

[](#advanced-concepts)

This is a „skeleton” of the steps required to do something more complicated within this library. For example, we want to use mapped interfaces/abstract on DTOs. Assume structure:

```
interface SomeDTOInterface {

}
```

```
use Er1z\FakeMock\Annotations\FakeMock as FakeMock;
use Er1z\FakeMock\Annotations\FakeMockField as FakeMockField;

/**
 * @FakeMock()
 */
class InnerDTO implements SomeDTOInterface {

    /**
     * @FakeMockField()
     */
    public $field;

}
```

```
use Er1z\FakeMock\Annotations\FakeMock as FakeMock;
use Er1z\FakeMock\Annotations\FakeMockField as FakeMockField;

/**
 * @FakeMock()
 */
class MainDTO {

    /**
     * @FakeMockField()
     * @var SomeDTOInterface
     */
    public $nested;

}
```

Running basic FakeMock scenario will produce nothing — `$nested` is `null`. We have to tell the library, what object should we map to desired interface.

```
$generators = GeneratorChain::getDefaultGeneratorsSet();

foreach($generators as $g)
{
    if( $g instanceof RecursiveGenerator::class )
    {
        $g->addClassMapping(SomeDTOInterface::class, InnerDTO::class);
    }
}

$generatorChain = new GeneratorChain($generators);

$fakemock = new FakeMock(null, $generatorChain);

$mainDto = new MainDto();
$result = $fakemock->fill($mainDto);
```

Of course, you also can map interfaces using annotations on the global and/or local scope:

```
use Er1z\FakeMock\Annotations\FakeMock as FakeMock;
use Er1z\FakeMock\Annotations\FakeMockField as FakeMockField;

/**
 * @FakeMock(classMappings={"Namespace\SomeDTOInterface"=>"Some\Other\Class"})
 */
class MainDTO {

    /**
     * @FakeMockField()
     * @var SomeDTOInterface
     */
    public $nested;

    /**
     * @FakeMockField("mapClass"="Some\Other\Class")
     * @var SomeDTOInterface
     */
    public $secondNested;

}
```

Changelog
---------

[](#changelog)

*0.3.1*

- Fixed: value retrieval to PropertyInfo-based method

*0.3*

- New: option to specify Faker's locale and Faker Generator Registry

*0.2.1*

- Fixed: correct asserts group processing

*0.2*

- New: recursive fields processing

*0.1*

- First public version

###  Health Score

24

—

LowBetter than 32% of packages

Maintenance3

Infrequent updates — may be unmaintained

Popularity21

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% 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 ~17 days

Total

5

Last Release

2666d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/1813302?v=4)[Przemysław eRIZ Pawliczuk](/maintainers/er1z)[@er1z](https://github.com/er1z)

---

Top Contributors

[![er1z](https://avatars.githubusercontent.com/u/1813302?v=4)](https://github.com/er1z "er1z (2 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/er1z-fakemock/health.svg)

```
[![Health](https://phpackages.com/badges/er1z-fakemock/health.svg)](https://phpackages.com/packages/er1z-fakemock)
```

###  Alternatives

[phpbench/phpbench

PHP Benchmarking Framework

2.0k13.0M627](/packages/phpbench-phpbench)[graham-campbell/analyzer

Checks if referenced classes really exist.

29594.5k112](/packages/graham-campbell-analyzer)[silverleague/ideannotator

Generate PHP DocBlock annotations for DataObject and DataExtension databasefields and relation methods

4768.0k43](/packages/silverleague-ideannotator)[refinery29/test-util

Provides a test helper, generic data providers, and assertions.

1554.0k3](/packages/refinery29-test-util)

PHPackages © 2026

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