我在Laravel 5.3中有一组用于测试API控制器的单元测试。当我们运行测试时,控制器会调用Model::fill($request->all())
。在正常执行代码时,这很好用。但在我们的测试中,它似乎忽略了受保护的属性。例如,在我们的UserController测试中,它通过password_confirmation = "password"
作为UPDATE语句的一部分,即使模型本身明确地防范它。以下是我们代码的示例:
// the test
public function testUpdate()
{
$user = factory(User::class)->create();
$password = '^MyIns3curePassw0rd';
$this->json('POST', 'api/users/'.$user->id.'/update', [
'name' => $user->name,
'email' => $user->email,
'password' => $password,
'password_confirmation' => $password,
])->assertResponseOk();
$this->seeJson([ 'name' => $user->name ]);
}
// the controller
public function update(UserRequest $request, $userId)
{
$user = null;
$this->db->transaction(function () use ($userId, &$user) {
$user = User::findOrFail($userId);
$user->fill($this->request->all());
$user->save();
});
return response()->json($user);
}
// the model
class User extends Model implements AuthenticatableContract, AuthorizableContract, CanResetPasswordContract
{
use Authenticatable, Authorizable, CanResetPassword, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = ['name', 'email', 'password'];
/**
* The attributes that aren't mass assignable.
*
* @var array
*/
protected $guarded = ['password_confirmation'];
}
是否有这种情况发生,我能解决吗?我发现了一些类似的问题,特别是Laravel 5: Model->fill() ignores $fillable property in unit tests,但是一切似乎都是针对5.1之前的版本而我们运行的是5.3.x(我已经在5.3.9上进行了测试,这是我们之前所做的,以及30年3月5日)