Skip to content

Generators ​

This document provides a detailed comparison between the available fake data generators and a migration guide for switching between them.

Available Generators ​

Faker ​

  • Package: FakerPHP/Faker
  • Minimum PHP: 8.2+ (project requirement)
  • Install: composer require --dev fakerphp/faker
  • Best for: Mature, feature-rich data generation with extensive locale support

Dummy ​

  • Package: johnykvsky/dummygenerator
  • Minimum PHP: 8.3+
  • Install: composer require --dev johnykvsky/dummygenerator
  • Best for: Modern PHP 8.3+ projects, native enum support, the alternative generator adapter

How the default is chosen ​

When FixtureFactories.generatorType is unset and you don't pass $type to CakeGeneratorFactory::create(), the plugin auto-detects which library is installed:

  1. Explicit Configure::write('FixtureFactories.generatorType', ...) always wins.
  2. Otherwise, if fakerphp/faker is installed, 'faker' is used.
  3. Otherwise, if johnykvsky/dummygenerator is installed, 'dummy' is used.
  4. If neither is installed, a FixtureFactoryException is thrown pointing at the install commands.

This means single-library installs "just work" with no extra config, while existing setups that have both libraries installed keep their previous faker-first behavior.

Key Differences ​

1. Enum Support ​

Faker (requires shim methods):

php
// Get random enum case (returns the enum object)
$status = $this->getGenerator()->enumCase(TestStatus::class);

// Get random backed enum value (returns string/int)
$statusValue = $this->getGenerator()->enumValue(TestStatus::class);

DummyGenerator (native support):

php
// Get random enum case (native method)
$status = $this->getGenerator()->enumCase(TestStatus::class);

// Get random backed enum value
$statusValue = $this->getGenerator()->enumValue(TestStatus::class);

2. Locale Support ​

Faker:

  • Full locale support with locale-specific data
  • 50+ locales available
  • Example: CakeGeneratorFactory::create('fr_FR')

DummyGenerator:

  • The plugin adapter ignores the locale parameter
  • Use Faker when locale-specific output matters
  • Focuses on generic data generation

3. Method Compatibility ​

Most methods work identically across both generators. However, some methods are shimmed for compatibility:

MethodFakerDummyGeneratorNotes
uuid()NativeMapped to uuid4()Both generate valid UUIDs
realText()NativeMapped to text()Same behavior
randomAscii()NativeShimmedReturns ASCII character (33-126)
enumCase()ShimmedNativeRecommended for enums
enumValue()ShimmedShimmedWorks on both

4. Seeding Behavior ​

Both generators support seeding for reproducible test data. By default, factories are seeded with 1234. Each factory class mixes its class name into that seed, so two factories with the same definition still produce different values. A shared generator set via BaseFactory::setDefaultGenerator() uses the plain seed and one sequence for all factories. Faker seeds PHP's process-wide mt_rand state, so with Faker a factory's values can still shift when another factory creates its generator first; DummyGenerator keeps its random state per generator. You can configure a different seed globally:

php
Configure::write('FixtureFactories.seed', 9999);

Faker:

php
$generator->seed(1234);

DummyGenerator:

php
$generator->seed(1234); // Uses XoshiroRandomizer internally

5. Measuring performance ​

Generator overhead depends on the selected methods, associations and database writes. Measure representative factories in your own test suite before choosing a generator for speed. This plugin does not provide comparative timing or memory benchmarks.

Switching Generators ​

Configuration ​

Set the generator type in your tests/bootstrap.php or test configuration:

php
use Cake\Core\Configure;

// Use Faker
Configure::write('FixtureFactories.generatorType', 'faker');

// Use DummyGenerator
Configure::write('FixtureFactories.generatorType', 'dummy');

If you have only one of the two libraries installed, you can leave this key unset — the plugin auto-detects which one is available.

Or set it per-factory:

php
$article = ArticleFactory::new()
    ->setGenerator('dummy')
    ->build();

Note: By default, setGenerator() only affects the current factory instance. Set FixtureFactories.instanceLevelGenerator to false if you need the legacy global behavior. See Fixture Factories.

Migration Guide: Faker → DummyGenerator ​

Step 1: Install DummyGenerator

bash
composer require --dev johnykvsky/dummygenerator

Step 2: Update Configuration

php
// In tests/bootstrap.php
Configure::write('FixtureFactories.generatorType', 'dummy');

Step 3: Test Your Factories

Run your test suite to ensure compatibility:

bash
vendor/bin/phpunit

Step 4: (Optional) Remove Faker

If you no longer need Faker:

bash
composer remove --dev fakerphp/faker

Migration Guide: DummyGenerator → Faker ​

Step 1: Install Faker

bash
composer require --dev fakerphp/faker

Step 2: Update Configuration

php
// In tests/bootstrap.php
Configure::write('FixtureFactories.generatorType', 'faker');

Step 3: Update Enum Methods (if using)

enumCase() and enumValue() work on both, so no changes needed unless you're using DummyGenerator-specific features.

Step 4: Adjust for Locale (if needed)

Take advantage of Faker's locale support:

php
$generator = CakeGeneratorFactory::create('fr_FR');

Step 5: Test Your Factories

Run your test suite:

bash
vendor/bin/phpunit

Common Pitfalls ​

1. PHP Version Requirements ​

Problem: DummyGenerator requires PHP 8.3+

Solution: Check your PHP version before switching:

bash
php -v

2. Locale-Specific Data ​

Problem: DummyGenerator doesn't support locale-specific data like Faker

Solution: If you need locale-specific data, stick with Faker or implement custom data providers

3. Unique Values ​

Problem: Different retry mechanisms for unique values

Solution: Both support unique() modifier, but DummyGenerator has a custom retry mechanism (10,000 attempts vs Faker's default)

php
// Works on both
$generator->unique()->email();

Best Practices ​

1. Keep Factory Code Generator-Agnostic ​

Write factory code that works with both generators:

php
// Good - works with both
'email' => $this->getGenerator()->email(),
'name' => $this->getGenerator()->name(),
'status' => $this->getGenerator()->enumCase(TestStatus::class),

// Avoid generator-specific methods unless necessary

2. Use Configuration for Switching ​

Don't hardcode generator selection in factories:

php
// Good - use configuration
Configure::write('FixtureFactories.generatorType', 'dummy');

// Good - per-factory override
ArticleFactory::new()->setGenerator('dummy')->build();

// Good - set global default explicitly
BaseFactory::setDefaultGenerator('dummy');

Tip: Leave FixtureFactories.instanceLevelGenerator enabled so that setGenerator() stays scoped to the current factory instance. See Fixture Factories.

3. Test with Both Generators (Optional) ​

If your library supports multiple PHP versions, test with both:

yaml
# .github/workflows/ci.yml
matrix:
  php: ['8.2', '8.3', '8.4']
  generator: ['faker', 'dummy']
  exclude:
    - php: '8.2'
      generator: 'dummy'

4. Seed for Reproducible Tests ​

Factories are seeded with 1234 by default for reproducible data, combined with the factory class name so two factories do not start on the same sequence. You can configure a different seed globally:

php
// In tests/bootstrap.php or config/app.php
Configure::write('FixtureFactories.seed', 9999);

See config/app.example.php in this plugin for all available configuration options.

Feature Matrix ​

FeatureFakerDummyGenerator
Basic data types✅✅
Text generation✅✅
Date/time✅✅
Internet (email, URL)✅✅
Person (name, title)✅✅
Address✅✅
Phone numbers✅✅
Company✅✅
UUID✅✅
Colors✅✅
Credit cards✅✅
Barcodes (EAN, ISBN)✅✅
Locale support✅ FullNot used by the adapter
Native enum support⚠️ Shimmed✅ Native
unique() modifier✅✅
optional() modifier✅✅
Seeding✅✅
Minimum PHP version8.2+8.3+

Troubleshooting ​

"Class not found" errors ​

Faker not found:

Faker library is not installed. Please install it using: `composer require --dev fakerphp/faker`

DummyGenerator not found:

DummyGenerator library is not installed. Please install it using: `composer require --dev johnykvsky/dummygenerator`

Solution: Install the required package.

Method not found ​

Problem: A method works with one generator but not the other

Solution: Check the compatibility table above. Most methods are shimmed, but some advanced features may differ.

Additional Resources ​

FAQ ​

Which generator should I use? ​

  • Use Faker if you need extensive locale support or need to support PHP < 8.3
  • Use DummyGenerator if you're on PHP 8.3+ and want a modern, lean solution with native enum support

Can I use both generators in the same project? ​

Yes! You can configure different generators per-factory or switch globally. However, it's recommended to use one consistently for maintainability.

Will my existing factories break if I switch? ​

Most likely not. The plugin provides compatibility shims for common methods. However, test your factories after switching.

How do I contribute new methods? ​

Add them to GeneratorInterface and implement in both FakerAdapter and DummyGeneratorAdapter, ensuring compatibility across both generators.

Can I create a custom generator? ​

Yes! Implement GeneratorInterface and register it:

php
use CakephpFixtureFactories\Generator\CakeGeneratorFactory;

CakeGeneratorFactory::registerAdapter('custom', MyCustomAdapter::class);

Configure::write('FixtureFactories.generatorType', 'custom');

Released under the MIT License.