I loved John's post about class-based model factories and wanted to take it a couple of steps further.
Problem: Multiple facade-based uses behave statically
From https://twitter.com/jason_varga/status/998352169412775936
Caleb's solution: https://twitter.com/calebporzio/status/998569618103992320
My adapted solution:
- Make an abstract factory class that handles clearing the resolved instance
- Change the
create
method in the child factory classes tomodel
Tweak: Prevent extra use statements
I wasn't super fond of importing a separate class with a Factory
suffix.
My IDE's import command kept importing the actual factory class instead of the facade.
Instead of needing to use Facades\MyFactory
throughout tests, we can add a factory()
method to the model's class.
Also, since the docblock returns the actual factory class, your IDE gives the appropriate method hints.
In tests, you're probably already importing the model anyway so now there's one less thing to worry about.
Before:
use App\Season;
use Facades\App\Factories\SeasonFactory;
SeasonFactory::create();
Season::count(); // Maybe you're making assertions using the model class
After:
use App\Season;
Season::factory()->create();
Season::count();