SQLSTATE [23000] путем добавления фиктивного теста - PullRequest
0 голосов
/ 09 мая 2019

Оба моих теста переходят в зеленое состояние всякий раз, когда я запускаю их отдельно, но я запускаю SQLSTATE [23000] в первом тесте всякий раз, когда я запускаю их вместе.Первый тест - это тест, который я сделал ранее, который имеет смысл для приложения, второй - фиктивный тест, как вы видите.

Я возобновил сообщение об ошибке из-за большого количества классов из laravelчто он показывает, но указывает на строку 27 ('user_id' => 1).

Test

<?php

namespace Tests\Unit;

use App\User;
use App\Tournament;
use Tests\TestCase;
use Illuminate\Support\Facades\Event;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;

class TournamentTest extends TestCase
{
    /**
     * A basic unit test example.
     *
     * @return void
     */
    use RefreshDatabase;

    protected function setUp() : void
    {
        parent::setUp();
        $this->withoutExceptionHandling();
        factory(User::class)->create();
        factory(Tournament::class)->create([
            'user_id' => 1
        ]);
    }

    /** @test **/
    public function index_page_shows_tournaments()
    {
        $user = User::first();

        $response = $this->actingAs($user)->get('/tournaments');

        $response->assertViewIs('tournaments.index');
    }

    /** @test **/
    public function create_tournament_shows_number_of_challengers()
    {
        $this->assertTrue(true);
    }
}

Ошибка

There was 1 error:

1) Tests\Unit\TournamentTest::create_tournament_shows_number_of_challengers
Illuminate\Database\QueryException: SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`torneio`.`tournaments`, CONSTRAINT `tournaments_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)) (SQL: insert into `tournaments` (`user_id`, `name`, `interval`, `round`, `chal_num`, `status`, `updated_at`, `created_at`) values (1, Best Cross-group neutral support, 38, 1, 8, 1, 2019-05-09 00:56:44, 2019-05-09 00:56:44))

/home/tadeusvult/dev/torneio/tests/Unit/TournamentTest.php:27

Caused by
PDOException: SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`torneio`.`tournaments`, CONSTRAINT `tournaments_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`))

1 Ответ

0 голосов
/ 11 мая 2019

Ошибка нарушения ограничения говорит о том, что в таблице users нет строки с id = 1. SELECT * FROM users WHERE id = 1 вернется пустым.

В документе Laravel такое поведение не упоминается - Откат транзакции по-прежнему увеличивает первичный ключ . См. Также документ MySQL: «Потерянные» значения автоинкремента и пробелы в последовательности .

Что происходит внутри setUp() с use RefreshDatabase;:

protected function refreshTestDatabase()
{
    if (! RefreshDatabaseState::$migrated) {
        $this->artisan('migrate:fresh', ...);

        ...

        RefreshDatabaseState::$migrated = true;
    }
    $this->beginDatabaseTransaction();
}

https://github.com/laravel/framework/blob/5.8/src/Illuminate/Foundation/Testing/RefreshDatabase.php#L52

Когда начинается TournamentTest, auto_increment в таблице users будет сброшено на migrate:fresh, но оно не сбрасывается в каждом методе теста. Другими словами, когда create_tournament_shows_number_of_challengers() работает, нет строки из index_page_shows_tournaments() из-за отката, но auto_increment по-прежнему возвращает 2.

Попробуйте распечатать идентификатор в setUp(). В любом случае, лучше не использовать жестко закодированный номер:

protected function setUp() : void
{
    parent::setUp();
    $this->withoutExceptionHandling();
    $user = factory(User::class)->create();

    var_dump($user->id); // see what's going on

    factory(Tournament::class)->create([
        'user_id' => $user->id // clearer intention
    ]);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...