Laravel 8 - 测试套件未触发特征并导致“违反完整性约束”错误

问题描述

我有一个 Trait,我在应用中的多个模型上使用它来在模型上设置 UUID

<?PHP

namespace App\Traits;

use Illuminate\Support\Str;

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

正常使用应用程序时它工作正常,但是当我尝试编写测试以通过 post route 创建模型并转储 response 我得到一个 {{1} } 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); }

其他一切都运行良好,但我是编写测试的新手,不知道如何解决这个问题。

我使用 Trait 的原因是为了避免在持久化到数据库时概述所有列值,因为我使用 $table->uuid('uuid')->unique(); 来填充模型:

$request->validated()

很明显,因为 UUID 没有在这里设置,它是由一个 Trait 完成的,它没有通过测试。如果我删除 Trait 并执行以下操作,我可以让测试通过并让应用程序仍然工作:

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

这很好,我可以接受,但我想更多地了解 Trait 没有触发的原因以及如何绕过它。

编辑: 只是根据下面的答案添加更多内容,正确定义了可填写字段:

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

解决方法

我认为这是模型的问题。 Venue 模型应使用 protected $fillable = ['uuid'];。 Laravel 默认保护质量分配。如果您在创建模型上提供数组,Laravel 不允许这样做。您需要提供一个受保护的可填充数组,因此laravel 只能为这些字段解锁。