这两项测试用于重置密码。我正在使用Laravel开箱即用的基本版本。第一次测试失败了。第二个测试是通过。它们非常相似。我不明白为什么第一次测试失败了。
在第一次测试中:
它一直告诉我我的电子邮件有错误。我不明白为什么。
<?php
namespace Tests\Controllers\Unit;
use Tests\TestCase;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Foundation\Testing\RefreshDatabase;
class ResetPasswordTest extends TestCase
{
use RefreshDatabase;
// This test is currently failing. It's saying I have error with email.
public function test_does_change_a_users_password()
{
// Create user
$user = factory('App\User')->create();
// This post route creates a new password reset token and stores it into the database.
$this->post(route('password.email'), ['email' => $user->email]);
// I get the token
$token = DB::table('password_resets')->whereEmail($user->email)->first()->token;
$this->from(route('password.reset', $token));
// Change password with the correct data
$response = $this->post('password/reset', [
'token' => $token,
'email' => $user->email,
'password' => 'password',
'password_confirmation' => 'password'
]);
// This is true... It tells me I have an error with my email.
$reponse->assertSessionHasErrors('email');
// This is false. The password is not changed to the new password.
$this->assertTrue(Hash::check('password', $user->fresh()->password));
}
// This test is the working one.
public function test_does_change_a_users_password2()
{
$user = factory('App\User')->create();
$token = Password::createToken($user);
$new_password = 'bestpassword99';
DB::table('password_resets')->insert([
'token' => $token,
'email' => $user->email,
]);
$this->from(route('password.reset', $token));
$response = $this->post('password/reset', [
'token' => $token,
'email' => $user->email,
'password' => $new_password,
'password_confirmation' => $new_password
]);
$this->assertTrue(Hash::check($new_password, $user->fresh()->password));
}
}
答案 0 :(得分:0)
如果您使用dd($response)
检查回复,则可以看到Laravel抱怨令牌无效。
但为什么呢? - Laravel不会在数据库中存储确切的令牌。它存储令牌的哈希值。这是为了确保获得数据库读取权限的人不能(轻松)重置用户密码。
因此,您希望获取发送给用户的令牌,而不是从数据库中获取哈希值。
让我们尝试从通知中提取令牌:
$bag = new \stdClass();
Notification::assertSentTo($user, \Illuminate\Auth\Notifications\ResetPassword::class, function ($notification) use ($bag) {
$bag->token = $notification->token;
return true;
});
$token = $bag->token;
并将其放入测试中:
/** @test */
public function does_change_a_users_password()
{
Notification::fake();
// Create user
$user = factory(User::class)->create();
// This post route creates a new password reset token and stores it into the database.
$this->post(route('password.email'), ['email' => $user->email]);
// get the password reset token
$bag = new \stdClass();
Notification::assertSentTo($user, ResetPassword::class, function ($notification) use ($bag) {
$bag->token = $notification->token;
return true;
});
$token = $bag->token;
$this->from(route('password.reset', $token));
// Change password with the correct data
$response = $this->post('password/reset', [
'token' => urlencode($token),
'email' => $user->email,
'password' => 'password',
'password_confirmation' => 'password'
]);
//$response->assertSessionHasErrors('password');
// Ensure password is changed.
$this->assertTrue(Hash::check('password', $user->fresh()->password));
}