Laravel 5.5 PHPunit 测试-“尚未设置外观根。”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46452753/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 16:44:10  来源:igfitidea点击:

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

laravellaravel-5phpunitfacadelaravel-5.5

提问by Justin Anthony

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 Schemafacades 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.

当我在 上执行 try/catch 时DB::Connection()->getPdo();,我收到错误A 门面根尚未设置。我相信Schema在我尝试添加 try/catch 之前,外墙也发生了这种情况。测试目录当然在 app 目录之外,我觉得它与此有关,但我还没有成功弄清楚。

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');
        });
    }
}

回答by Marcin Nabia?ek

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

问题是您不能在 setUpBeforeClass 中执行此操作,因为许多事情都在setUp方法中运行。如果您查看此运行顺序,您将看到setUpBeforeClasssetUp方法之前运行,而 TestCase 类在该setUp方法中执行了许多操作。它看起来像这样:

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 setUpand tearDownmethods with your own implementation like this:

所以,你应该做的是创造自己setUptearDown与自己的实现这样的方法:

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

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

回答by Justin Anthony

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.

对于那些对我发现使用 Capsule 工作的其他方法感到好奇的其他人,这里是代码。这将适用于setUpBeforeClass()setUp()。这可以而且应该更抽象,但这就是它的要点。

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
        ]);
    }
}