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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30940847/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 11:48:35  来源:igfitidea点击:

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

phpunit-testinglaravelphpunitlaravel-5

提问by rvignacio

I have a user controller with the following validation rules:

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

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

My User.php model defines the fillable properties as:

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

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

To pass the confirmedvalidation, I have to send both passwordand password_confirmationfields in the POST request.

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

During development everything works fine, but in unit tests I'm getting a database error. It tries to insert data into a password_confirmation column. It's like it ignores the $fillablearray.

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

I know about the "laravel losts event handlers between tests" bug/issue (https://github.com/laravel/framework/issues/1181). So I think that maybe I'm missing to call some model function aside from Model::boot()(I'm calling User::boot()in the test's setUp()function).

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

Thanks,

谢谢,

Edit

编辑

Reading the Model.php source, I've found that someone is calling Model::unguard()https://github.com/laravel/framework/blob/5.1/src/Illuminate/Database/Eloquent/Model.php#L2180after the setUp() function and before the test. If I call User::reguard()at the beggining of the test it passes, but (I don't know why), the unguard() and reguard() functions get called multiple times and the test gets really slow.

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

回答by rvignacio

Found the problem: the base seeder in v5.0.x only called Model::unguard() (https://github.com/laravel/laravel/blob/v5.0.22/database/seeds/DatabaseSeeder.php#L15) while v5.1.x was updated and added a call to Model::reguard() (https://github.com/laravel/laravel/blob/v5.1.0/database/seeds/DatabaseSeeder.php#L19) (I was using v5.0.22).

发现问题: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)。

回答by Jazerix

Fillable only applies to MassAssignment. When you're creating a new instance, like what you're doing above, you're not triggering the mass assignment event.

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

You could do something like this: If you're creating the user anyway, you might as well do:

你可以做这样的事情:如果你无论如何都要创建用户,你最好这样做:

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

If you just want to instantiate the user, without persisting the data, you could do something like this:

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

$user = new User($request);