If you’ve ever tried to use a Laravel model factory inside a PHPUnit data provider, then you were likely greeted with an error message resembling
"A facade root has not been set". After scratching your head for a few minutes, you probably (wisely) decided that life is too short and then promptly scrapped the whole approach. The issue that you encountered is an expected consequence of the lifecycle of PHPUnit tests. In PHPUnit, data providers are called before a test’s
setUp method. If you look inside the
Illuminate\Foundation\Testing\TestCase class, which is the abstract class that Laravel feature tests ultimately extend, you’ll see the following snippet:
setUp method inside that class is responsible for booting the Laravel framework in tests via the
refreshApplication method. As data providers are executing before that
setUp method has been called, you’re not going to have access to Laravel functionality such as facades and model factories at that point. You might think that this is the end of the road for using model factories inside your data providers. Fear not, there’s a neat trick that you can use to get around this limitation. If you wrap the provider’s data set within a closure, this will cause the expression to be evaluated lazily.
The above approach does have the downside of requiring you to invoke the
Closure inside the body of your test, but it’s a relatively small price to pay. For the sake of completeness, I’ve included examples of returning a singular
User model in a data set as well as returning an array of
If you want to learn more about PHPUnit data providers outside of the previously linked documentation, then I would highly recommend this blog post by Matt Barlow.