Laravel 5:Model->fill() 在单元测试中忽略$fillable属性


Laravel 5: Model->fill() ignores $fillable property in unit tests

我有一个具有以下验证规则的用户控制器:

public function store(Request $request)
{
    ...
    $this->validate($request, [
        'name' => 'required',
        'email' => 'email|required|unique:users',
        'password' => 'confirmed|max:32|min:8|required',
        'roles' => 'exists:roles,id|required',
    ]);
    $user = new User();
    $user->fill($request->all());
   ...
}

我的用户.php模型将可填充属性定义为:

protected $fillable = ['name', 'email'];

要通过confirmed验证,我必须在 POST 请求中同时发送passwordpassword_confirmation字段。

在开发过程中一切正常,但在单元测试中我收到数据库错误。它尝试将数据插入到password_confirmation列中。就像它忽略了$fillable数组一样。

我知道"laravel在测试之间丢失事件处理程序"错误/问题(https://github.com/laravel/framework/issues/1181)。所以我认为除了Model::boot()之外,我可能缺少调用一些模型函数(我在测试的setUp()函数中调用User::boot())。

谢谢

编辑

阅读 Model.php源代码,我发现有人在 setUp() 函数之后和测试之前调用Model::unguard() https://github.com/laravel/framework/blob/5.1/src/Illuminate/Database/Eloquent/Model.php#L2180。如果我在测试开始时调用User::reguard()它会通过,但是(我不知道为什么),unguard() 和 reguard() 函数被多次调用,测试变得非常慢。

发现问题:v5.0.x 中的基本播种器仅调用 Model::unguard() (https://github.com/laravel/laravel/blob/v5.0.22/database/seeds/DatabaseSeeder.php#L15),而 v5.1.x 已更新并添加了对 Model::reguard() (https://github.com/laravel/laravel/blob/v5.1.0/database/seeds/DatabaseSeeder.php#L19) 的调用(我使用的是 v5.0.22)。

Fillable 仅适用于 MassAssignment。创建新实例时,就像上面所做的那样,不会触发批量分配事件。

你可以做这样的事情:无论如何,如果您要创建用户,则不妨执行以下操作:

$user = User::create($request->all);

如果您只想实例化用户而不保留数据,则可以执行以下操作:

$user = new User($request);