【发布时间】:2021-10-22 03:20:53
【问题描述】:
我正在实现https://laravel.com/docs/8.x/passwords 的 Laravel 文档中描述的密码重置功能。我的重置密码方法如下:
public function doPasswordReset(Request $request)
{
$request->validate([
'token' => 'required',
'email' => 'required|email',
'password' => 'required|min:8|confirmed',
]);
$status = Password::reset(
$request->only('email', 'password', 'password_confirmation', 'token'),
function ($user, $password) {
$user->forceFill([
'password' => Hash::make($password)
]);
//remember token not needed
//->setRememberToken(Str::random(60));
$user->save();
event(new PasswordReset($user));
}
);
return $status === Password::PASSWORD_RESET
? redirect()->route('login')->with('status', __($status))
: back()->withErrors(['email' => [__($status)]]);
}
我对这个方法的测试是:
/** @test */
public function the_user_can_update_their_password()
{
ParentUser::factory()->create([
'email' => 'user@domain.com',
'password' => Hash::make('oldpassword')
]);
$token = Password::createToken(ParentUser::first());
Password::shouldReceive('reset')
->once()
->withSomeofArgs([
'email' => 'user@domain.com',
'password' => 'newpassword',
'password_confirmation' => 'newpassword',
'token' => $token
])
->andReturn(Password::PASSWORD_RESET);
$response = $this->post(route('password.update'), [
'email' => 'user@domain.com',
'password' => 'newpassword',
'password_confirmation' => 'newpassword',
'token' => $token
]);
$response->assertRedirect(route('login'));
//failures from here
$this->assertEquals(Hash::make('newpassword'), Hash::make(ParentUser::first()->password));
$this->assertNotEquals(Hash::make('oldpassword'), Hash::make(ParentUser::first()->password));
Event::fake();
Event::assertDispatched(PasswordReset::class, ParentUser::first());
}
我的问题是最后三个断言失败。我意识到这种情况正在发生,因为我的模拟没有调用闭包来影响密码更改并引发事件。所以我的问题是是否可以模拟函数调用的一些参数。
我正在考虑的一个解决方案是将闭包分解为自己的方法并单独测试。在没有其他任何东西的情况下,我认为这可能是唯一的方法。
【问题讨论】:
-
Password::shouldReceive('reset')这会模拟对reset的调用,实际上不会更改密码。如果您将其注释掉,那么它可能会起作用。注意:由于您使用的是框架代码,我认为您不应该尝试验证密码是否已更改。只有Password::reset会被正确的参数调用。您可以假设 Laravel 框架测试已经测试过它可以按预期工作
标签: php laravel testing mocking