Набор тестов Laravel 8 не запускает признаки и вызывает ошибки «Нарушения целостности».

#php #laravel #laravel-8 #laravel-testing

Вопрос:

У меня есть a Trait , который я использую на нескольких моделях в своем приложении для установки a UUID на модели:

 <?php

namespace AppTraits;

use IlluminateSupportStr;

trait UsesUuid
{
    protected static function bootUsesUuid()
    {
        static::creating(function ($model) {
            if (!$model->uuid) {
                $model->uuid = (string) Str::orderedUuid();
            }
        });
    }
}
 

Это нормально работает при обычном использовании приложения, но когда я пытаюсь написать тесты для создания модели с помощью a post route и дампа response , я получаю Integrity constraint violation: 19 NOT NULL constraint failed: venues.uuid 500 ошибку.

Примером теста, который я провожу, является:

 public function testOwnerCanSuccessfullyCreateVenue()
{
    $amenity = Amenity::inRandomOrder()->pluck('id')->first();

    $response = $this->actingAs($this->createdUser('owner'))->post(route('venues.store'), [
        "name" => "create-name",
        "address_line_1" => "create-address_line_1",
        "address_line_2" => "create-address_line_2",
        "county" => "create-county",
        "postcode" => "create-postcode",
        "phone_number" => "create-phone_number",
        "notes" => "create-notes",
        "amenities" => [$amenity]
    ]);

    dd($response);
}
 

И колонка в моей миграции такова $table->uuid('uuid')->unique();

Все остальное работает блестяще, но я новичок в написании тестов и не знаю, как обойти эту проблему.

Причина, по которой я использовал признак, заключалась в том, чтобы обойти выделение всех значений столбцов при сохранении в базе данных, как я использую $request->validated() для заполнения модели:

 $venue = Venue::create($request->validated()); 
 

И, очевидно, из-за того, что UUID здесь не задается, это делается с помощью признака, который не прошел тест. Я могу пройти тест, и приложение все еще будет работать, если я удалю эту черту и сделаю это:

 $venue = Venue::create(
    $request->validated()   ['uuid' => Str::orderedUuid()]
); 
 

Что хорошо, я могу с этим смириться, но я хотел бы больше понять, почему эта Черта не стреляет и как ее обойти.

Изменить: Просто чтобы добавить больше, основываясь на приведенном ниже ответе, заполняемые поля определены правильно:

 /**
 * The attributes that are mass assignable.
 *
 * @var array
 */
protected $fillable = [
    'uuid',
    'name',
    'address_line_1',
    'address_line_2',
    'county',
    'postcode',
    'phone_number',
    'notes',
];
 

Ответ №1:

Я думаю, что это проблема в модели. Venue модель должна использовать protected $fillable = ['uuid']; . По умолчанию Laravel защищает массовое назначение. В случае, если вы предоставляете массив при создании модели, Laravel этого не разрешает. Вам необходимо предоставить защищенный заполняемый массив, чтобы laravel мог разблокировать только эти поля.

Комментарии:

1. Если бы это было так, обходной путь не сработал бы, модель назначена правильно