Well, after a little research (of the classes), I decided that the Laravel application was not yet created by calling the setUpBeforeClass() static method.
The Laravel container is created for the first time when setUp() is called in \vendor\laravel\framework\src\illuminate\Foundation\Testing\TestCase.php . Therefore, it works fine when I go to my setUp() method.
Then the container is stored in the $app property, stored in \vendor\laravel\framework\src\illuminate\Foundation\Testing\ApplicationTrait.php .
I can manually create an instance of the container by adding this code to the setUpBeforeClass() method:
$app = require __DIR__.'/../bootstrap/app.php'; $app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
But this method seems pretty hacky, and I don't like it.
Instead, I moved the seeding code to the setUp () method, but only sowed the database if the class properties were empty. Therefore, it is only visited the first time setUp() called. Any subsequent calls are not attended:
class CommentTest extends TestCase { use DatabaseMigrations; protected static $blog; protected static $comments; public function setUp() { parent::setUp(); $this->runDatabaseMigrations(); if (is_null(self::$blog)) { self::$blog = factory(App\Models\Content\Blog::class, 1)->create(); self::$comments = factory(App\Models\Content\Comment::class, 6)->create(); } } }
Combined with the Laravels DatabaseMigrations feature for testing, this is now a workflow:
- Phpunit is called
- The Test class is called, which contains the
DatabaseMigrations attribute. - Database Migration (Created Tables)
- The
setUp() method is called for the first time, which seeds the corresponding tables with test data - The test runs and accesses the test data.
- There is no
tearDown() method; instead, the DatabaseMigrations flag simply flushes the database, so my test does not need to worry about clearing the test data.
EDIT
Also, it seems (although I'm not 100%) that if you have your own setUp() method, you need to manually call runDatabaseMigrations() from the overridden setUp() method:
public function setUp() { parent::setUp(); $this->runDatabaseMigrations(); }
runDatabaseMigrations() does not seem to be automatically called if you overload the setUp() method.
I hope this helps, but if anyone else has a better solution, please let me know :)