Создание и удаление таблицы во время теста Laravel - PullRequest
0 голосов
/ 12 июня 2018

Я создал черту в своем приложении Laravel 5.6.Черта называется Projectable.Эта черта предназначена для использования в моделях Eloquent.Чтобы проверить эту черту, я хотел создать модель ProjectableStub для использования в тестах.Однако, поскольку это модель Eloquent, для нее требуется таблица.

Я хотел просто создать и удалить таблицу только для тестирования.Однако, когда я делаю это, кажется, что-то ломается в отношении функциональности RefreshDatabase.Чтобы продемонстрировать, я просто запускаю два теста, каждый из которых пытается создать модель Product с id = 1.Поскольку используется черта 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 с дублирующим идентификаторомиспользуется:

<?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) Tests \ Feature \ ProjectableTest :: example_second_test Illuminate \ Database \ QueryException: SQLSTATE [23000]: нарушение ограничения целостности: 1062 Повторяющаяся запись '1' для ключа 'PRIMARY '

Кто-нибудь знает, почему создание и удаление таблицы в тесте вызывает эту проблему?Есть ли лучший способ сделать это?Может быть, какой-нибудь способ добавить миграцию во время выполнения для этой новой таблицы?

1 Ответ

0 голосов
/ 13 июня 2018

Я думаю, что это может быть ответом:

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

Кажется, что до сих пор работает отлично.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...