Laravel修改密码表单的PHPUnit测试编写问题求助
解决Laravel修改密码PHPUnit测试断言失败的问题
嘿,这个问题我之前也碰到过!你猜的完全对——问题就出在Hash::make()的特性上。
问题根源
Laravel默认使用的Bcrypt哈希算法,每次调用Hash::make()生成的哈希值都是不一样的,哪怕是同一个明文密码。这是因为它会自动生成随机的盐值,所以两次哈希同一个密码得到的结果完全不同。你的测试里直接用Hash::make('newone')去匹配数据库里的密码,自然会断言失败,哪怕实际功能是正常的。
正确的测试写法
我们不能直接断言哈希后的字符串,而是要验证数据库里的哈希是否能匹配明文密码。这里有两种靠谱的方案:
方案一:重新查询用户并验证密码
更新密码后,重新从数据库拉取用户实例,然后用Hash::check()来验证密码是否正确:
$user = \factory(\App\User::class)->create(['password' => \Hash::make('password')]); $this->actingAs($user); // 用更简洁的put方法代替call $response = $this->put('/user/update-password', [ '_token' => csrf_token(), 'current_password' => 'password', 'new_password' => 'newone', 'repeat_new_password' => 'newone', ]); $response->assertStatus(302); // 重新获取更新后的用户 $updatedUser = \App\User::find($user->id); // 验证明文密码和数据库里的哈希是否匹配 $this->assertTrue(\Hash::check('newone', $updatedUser->password));
方案二:用闭包自定义数据库断言(Laravel 8+适用)
如果你想继续用assertDatabaseHas,可以通过闭包来做自定义验证:
$this->assertDatabaseHas('users', ['id' => $user->id], function ($query) { $query->whereRaw('password = ?', [\Hash::make('newone')]); });
不过第一种方案代码更直观,可读性更高,更推荐使用。
额外小建议
- 测试里尽量用Laravel提供的HTTP方法助手(比如
put()、post())代替call(),代码会更简洁。 - 可以加个重定向断言,比如
$response->assertRedirect('/dashboard')(根据你的实际跳转路径调整),让测试覆盖更完整。
内容的提问来源于stack exchange,提问作者Linas Lg
相关产品推荐
相关产品推荐

