【问题标题】:Laravel 5: Model->fill() ignores $fillable property in unit testsLaravel 5:Model->fill() 在单元测试中忽略 $fillable 属性
【发布时间】:2015-06-20 02:03:49
【问题描述】:

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

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

我的 User.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() 函数会被多次调用,并且测试变得非常慢。

【问题讨论】:

    标签: php unit-testing laravel phpunit laravel-5


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      你可以这样做: 如果您仍然要创建用户,您不妨这样做:

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

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

      $user = new User($request);
      

      【讨论】:

      • 调用Model::create($attributes) 最终会调用Model::fill() 函数see Eloquent/Model.php source。问题是它尊重 dev 中的 $fillable 数组,而不是测试中的数组。
      猜你喜欢
      • 1970-01-01
      • 2016-08-06
      • 1970-01-01
      • 2021-11-24
      • 1970-01-01
      • 1970-01-01
      • 2020-10-22
      • 1970-01-01
      • 2016-05-15
      相关资源
      最近更新 更多