【问题标题】:Creating and dropping a table during Laravel test在 Laravel 测试期间创建和删除表
【发布时间】:2018-06-12 14:09:23
【问题描述】:

我在我的 Laravel 5.6 应用程序中创建了一个 trait。该特征称为Projectable。此特征旨在供 Eloquent 模型使用。为了测试特征,我想创建一个ProjectableStub 模型以在测试中使用。但是,由于这是 Eloquent 模型,因此需要一个表格。

我想简单地创建和删除一个表来进行测试。但是,当我这样做时,RefreshDatabase 功能似乎有些问题。为了演示,我只是运行了两个测试,这两个测试都尝试使用id = 1 创建一个Product 模型。由于正在使用 RefreshDatabase 特征,这应该可以正常工作。而且,在下面的示例中,它确实:

<?php

namespace Tests\Feature;

use App\Product;
use Tests\TestCase;
use App\Concerns\Projectable;
use Illuminate\Support\Facades\Schema;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Database\Eloquent\Model as Eloquent;

class ProjectableTest extends TestCase
{
    use RefreshDatabase;

    public function setUp()
    {
        parent::setUp();

        //$this->createStubTable();
    }

    /**
     * @test
     */
    public function example_first_test()
    {
        factory(Product::class)->create(['id' => 1]);
    }

    /**
     * @test
     */
    public function example_second_test()
    {
        factory(Product::class)->create(['id' => 1]);
    }

    public function tearDown()
    {
        //$this->dropStubTable();

        parent::tearDown();
    }

    private function createStubTable()
    {
        Schema::create('stubs', function ($table) {
            $table->increments('id');
            $table->string('name');
            $table->timestamps();
        });
    }

    private function dropStubTable()
    {
        Schema::dropIfExists('stubs');
    }
}

class ProjectableStub extends Eloquent
{
    use Projectable;

    protected $table = 'stubs';

    protected $guarded = [];
}

但是,一旦我取消注释这两行以便创建和删除 stubs 表,我就会收到一条 SQL 错误,指出正在使用重复 ID:

<?php

namespace Tests\Feature;

use App\Product;
use Tests\TestCase;
use App\Concerns\Projectable;
use Illuminate\Support\Facades\Schema;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Database\Eloquent\Model as Eloquent;

class ProjectableTest extends TestCase
{
    use RefreshDatabase;

    public function setUp()
    {
        parent::setUp();

        $this->createStubTable();
    }

    /**
     * @test
     */
    public function example_first_test()
    {
        factory(Product::class)->create(['id' => 1]);
    }

    /**
     * @test
     */
    public function example_second_test()
    {
        factory(Product::class)->create(['id' => 1]);
    }

    public function tearDown()
    {
        $this->dropStubTable();

        parent::tearDown();
    }

    private function createStubTable()
    {
        Schema::create('stubs', function ($table) {
            $table->increments('id');
            $table->string('name');
            $table->timestamps();
        });
    }

    private function dropStubTable()
    {
        Schema::dropIfExists('stubs');
    }
}

class ProjectableStub extends Eloquent
{
    use Projectable;

    protected $table = 'stubs';

    protected $guarded = [];
}

1) 测试\功能\ProjectableTest::example_second_test Illuminate\Database\QueryException: SQLSTATE[23000]: 完整性 违反约束:1062 键 'PRIMARY' 的重复条目 '1'

有谁知道为什么在测试中创建和删除表会导致此问题?有没有更好的方法来解决这个问题?也许有办法在运行时为这个新表添加迁移?

【问题讨论】:

  • 你能解释一下为什么你需要为你的测试创建这个表,如果它不存在的话?
  • @RossWilson 这是因为我正在尝试测试特征本身的核心功能,而不是在任何特定模型中使用它的方式。换句话说,不同的模型将使用此特征,并且它们将各自指定不同的设置来影响特征为这些特定模型执行的操作。我计划分别使用 trait 为每个模型编写测试。我的目的是为 trait 的核心功能以及它可能使用的所有不同方式编写测试。
  • 我在测试的底部添加了ProjectableStub 模型。这就是我在实际测试中创建和使用的模型。但是,您可以在示例测试中看到我只是使用不同的Product 模型来演示该问题。在测试期间创建和修改表似乎会影响RefreshDatabase 功能,但我不知道为什么。

标签: php laravel phpunit


【解决方案1】:

我认为这可能是答案:

https://dev.mysql.com/doc/refman/8.0/en/implicit-commit.html

创建表会导致RefreshDatabase 创建的活动事务自动提交。

使存根表成为临时的就行了。这也意味着我也不需要删除表格,因为它会自动发生:

Schema::create('stubs', function ($table) {
    $table->temporary()
    $table->increments('id');
    $table->string('name');
    $table->timestamps();
});

目前看来运行良好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-19
    • 1970-01-01
    • 2015-05-02
    • 2011-10-24
    • 2013-10-16
    • 1970-01-01
    相关资源
    最近更新 更多