Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel 5.5 PHPunit Test - "A facade root has not been set."

When I do a try/catch on the DB::Connection()->getPdo();, I get the error A facade root has not been set. I believe it was happening with the Schema facades too before I tried adding the try/catch. The tests directory is, of course, outside of the app directory, and I have a feeling it has something to do with that, but I have not succeeded in figuring it out.

Here is the test class where this is happening:

<?php

namespace Tests\Models;

use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;
use App\Models\Discussion;
use App\User;
use Business\Database\Model;
use Illuminate\Database\Schema\Blueprint;
use Tests\TestCase;

class DiscussionModelTest extends TestCase
{
    /**
     * Create the tables this model needs for testing.
     */
    public static function setUpBeforeClass()
    {
        try {
            DB::connection()->getPdo();
        } catch(\Exception $e) {
            die($e->getMessage());
        }

        Schema::create('discussions', function (Blueprint $table) {
            $table->integer('id');
            $table->integer('user_id');

            $table->foreign('user_id')->references('id')->on('users');
        });

        Schema::create('users', function (Blueprint $table) {
            $table->integer('id');
        });
    }
}
like image 688
Justin Anthony Avatar asked Sep 27 '17 16:09

Justin Anthony


3 Answers

The thing is you cannot do this in setUpBeforeClass, because many things are run in setUp method. If you look at this order of run you will see setUpBeforeClass is run before setUp method and TestCase class is doing many things in the setUp method. It looks like this:

protected function setUp()
{
    if (! $this->app) {
        $this->refreshApplication();
    }

    $this->setUpTraits();

    foreach ($this->afterApplicationCreatedCallbacks as $callback) {
        call_user_func($callback);
    }

    Facade::clearResolvedInstances();

    Model::setEventDispatcher($this->app['events']);

    $this->setUpHasRun = true;
}

So what you should do is creating own setUp and tearDown methods with your own implementation like this:

protected function setUp()
{
   parent::setUp();
   // your code goes here
}

protected function tearDown()
{
   parent::tearDown();
   // your code goes here
}
like image 80
Marcin Nabiałek Avatar answered Dec 21 '22 14:12

Marcin Nabiałek


I get answer here

You shouldn’t, because a feature test would extend the TestCase class in your tests directory instead PHPUnit’s.

Remove:

use PHPUnit\Framework\TestCase;

And replace it with:

use Tests\TestCase;
like image 25
DEV Tiago França Avatar answered Dec 21 '22 16:12

DEV Tiago França


For anyone else who is curious as to the other method I found to work using Capsule, here is the code. this will work in both setUpBeforeClass() and setUp(). This could and should be more abstract, but this is the gist of it.

use Illuminate\Database\Capsule\Manager as Capsule;

class DiscussionModelTest extends TestCase
{
    /**
     * Create the tables this model needs for testing.
     */
    public static function setUpBeforeClass()
    {
        $capsule = new Capsule;

        $capsule->addConnection([
            'driver' => 'sqlite',
            'database' => ':memory:',
            'prefix' => '',
        ]);

        $capsule->setAsGlobal();

        $capsule->bootEloquent();

        Capsule::schema()->create('discussions', function (Blueprint $table) {
            $table->integer('id');
            $table->integer('user_id');

            $table->foreign('user_id')->references('id')->on('users');
        });

        Capsule::schema()->create('users', function (Blueprint $table) {
            $table->integer('id');
        });

        // Seed the faux DB
        Model::unguard();

        User::create([
            'id' => 13
        ]);

        Discussion::create([
            'id' => 5,
            'user_id' => 13
        ]);
    }
}
like image 45
Justin Anthony Avatar answered Dec 21 '22 16:12

Justin Anthony