davidbadura/fixtures
Flexible PHP fixtures library with YAML/JSON/TOML/PHP loaders, Faker support, automatic dependency resolution, configurable converters, tagging/filtering, validation via events, expression language, and persisters for Doctrine ORM/MongoDB and Propel.
Installation Add the package via Composer:
composer require davidbadura/fixtures
Publish the config (optional):
php artisan vendor:publish --provider="Davidbadura\Fixtures\FixturesServiceProvider"
Basic Fixture Loading
Define a fixture in database/fixtures/ (e.g., users.yml):
users:
- { id: 1, name: 'John Doe', email: 'john@example.com' }
- { id: 2, name: 'Jane Doe', email: null } # Nullable fields now supported
Load fixtures in a Laravel test or command:
use Davidbadura\Fixtures\Fixtures;
$fixtures = new Fixtures();
$fixtures->load('users');
First Use Case: Seeding Tests
Use in phpunit.xml or setUp():
public function setUp(): void
{
parent::setUp();
$this->artisan('db:seed', ['--class' => 'FixturesTestSeeder']);
}
Define Fixtures
Store fixtures in database/fixtures/ (supports .yml, .json, .php).
Example: roles.json
{
"roles": [
{ "id": 1, "name": "Admin" },
{ "id": 2, "name": "Editor", "description": null } # Nullable fields
]
}
Load with Dependency Resolution
Use Fixtures::load() with dependency chains:
$fixtures->load(['users', 'roles']); // Loads in order
$fixtures->load('posts', ['author_id' => 1]); // Dynamic references
Validation & Error Handling
Validate fixtures via config (config/fixtures.php):
'validation' => [
'users.*' => [
'required' => ['name', 'email'],
'nullable' => ['email'] // Explicitly allow nulls
]
],
Integration with Laravel
$this->call('fixtures:load', ['fixtures' => 'users,posts']);
Fixtures to the container:
$this->app->bind('fixtures', function ($app) {
return new Fixtures($app['config']);
});
Dynamic Fixtures with Nullable Fields Generate fixtures programmatically with nullable values:
$fixtures->add('dynamic_users', [
['name' => 'Alice', 'email' => 'alice@example.com'],
['name' => 'Bob', 'email' => null] // Nullable fields
]);
Dependency Order Matters
post.author_id) will fail silently or throw cryptic errors.Fixtures::loadWithDependencies().Nullable Field Handling
'validation' => [
'users.*' => [
'nullable' => ['email', 'description'] // Explicitly declare nullable fields
]
],
nullable in validation rules to avoid strictness errors.Config Overrides
config/fixtures.php) may conflict with package defaults.$fixtures = new Fixtures(config(['fixtures' => $customConfig]));
Archived Package Risks
Enable Verbose Logging Set in config:
'debug' => true,
Logs fixture loading steps to storage/logs/laravel.log.
Check Fixture Paths
Default paths are database/fixtures/ and tests/fixtures/.
Override via config:
'paths' => [
database => 'custom/fixtures/path',
],
Test Fixture Isolation Use transactions in tests:
public function tearDown(): void
{
DB::transaction(function () {
DB::table('users')->truncate();
});
}
Custom Fixture Types
Extend Davidbadura\Fixtures\Fixtures to support new formats (e.g., CSV):
class ExtendedFixtures extends Fixtures {
public function loadCsv(string $fixture) { /* ... */ }
}
Hooks for Post-Loading
Use events (if supported) or wrap Fixtures::load():
$fixtures->load('users');
event(new FixturesLoaded('users'));
Database-Specific Logic
Override getConnection() to target specific databases:
$fixtures->setConnection('mysql_secondary');
Nullable Field Validation
Customize validation for nullable fields in config/fixtures.php:
'validation' => [
'posts.*' => [
'nullable' => ['published_at', 'excerpt'],
'required_if' => ['published_at', 'excerpt', 'is_published']
]
],
How can I help you explore Laravel packages today?