We'll see in this post an alternative place to write fixtures in an Symfony application.
According to the Symfony Framework Best Practices, fixtures should be placed in src/DataFixtures/
.
I'll briefly argue against this.
Development, tests, and build stuff is supposed to be discarded once the application is built. Fixtures are precisely this, a set of files for testing and/or development purposes.
I would say we should place fixtures outside of src/
for the same reasons we write tests in the tests/
directory. It's better to not bloat the src/
with code that isn't business logic.
The golden rule is to not pollute src/
directory with non-runtime stuff.
Fixtures Under fixtures/
I propose to place fixtures inside the fixtures/
directory in the root of the project instead of src/DataFixtures/
.
From:
project/
└─ src/
└─ DataFixtures/
To:
project/
├─ fixtures/
└─ src/
Implementation
Let's make it real in your Symfony application. It may work with Symfony Demo as well.
Move Files
- Move the
src/DataFixtures/
directory to the root; - Rename it as
fixtures/
; and - Change its classes namespaces to
App\Fixtures
*.
At this point, the doctrine:fixtures:load
command doesn't work because it can't find fixtures anymore. If you try running it you'll get this error message:
[ERROR] Could not find any fixture services to load.
In order to fix it, we must:
- Inform Composer there is a new directory that contains classes (dev only); and
- Make the classes inside this directory loadable as service (dev only as well).
Fix Classes Autoloading
Add "App\\Fixtures\\": "fixtures/"
* to the autoload-dev
section in composer.json
.
"autoload-dev": {
"psr-4": {
+ "App\\Fixtures\\": "fixtures/",
"App\\Tests\\": "tests/"
}
},
Don't forget to run:
composer dump-autoload
Configure Services Loading
Make the new fixtures/
content* findable by loading them automaticaly in config/services_dev.yaml
.
# config/services_dev.yaml
services:
_defaults:
autowire: true
autoconfigure: true
App\Fixtures\:
resource: '../fixtures/*'
If you need fixtures in another mode (e.g. test
), create the corresponding file (e.g. config/services_test.yaml
) with the same content above.
Fin
The command below should work as before.
bin/console doctrine:fixtures:load
* I use App\Fixtures
instead of App\DataFixtures
as namespace. It's up to you to adopt it or not.
Top comments (3)
Good tip
Very nice tutorial :-)
Thank you!