Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
412 views
in Technique[技术] by (71.8m points)

Testing login scaffolding in Laravel with PHPunit

Can't make this pass the login test with Laravel scaffolding.

I tried accessing database $user with $user = User::first(); and also using factory User::factory()->create();. In both cases I'm able to successfully dd($user) info, so it means $user exists and can be accessed.

I also tried hardcoding credentials with bcrpyt() and Hash::make password - where the error also appears to happen.

I'm not ussing RefreshDatabase trait.

public function test_log_user()
{
    $this->withoutExceptionHandling();

    // $user = User::first();
    $user = User::factory()->create();
    // dd($user);

    $response = $this->post('/login', [
        'email' => $user->email,
        'password' => $user->password, //line 47
    ]);

    $response->getStatusCode();
    // $response->dumpHeaders();
    // $response->dump();
    $response->assertStatus(302);
}

Getting this error:

IlluminateValidationValidationException: The given data was invalid.

C:xampphtdocs eactReact-Laravelvinos-gdlestsFeatureAuthTest.php:47

I have already cleared cache, routes, config.

phpunit.xml:

<server name="APP_ENV" value="testing"/>
<server name="BCRYPT_ROUNDS" value="4"/>
<server name="CACHE_DRIVER" value="array"/>
<!-- <server name="DB_CONNECTION" value="sqlite"/>
<server name="DB_DATABASE" value=":memory:"/> -->
<server name="MAIL_MAILER" value="array"/>
<server name="QUEUE_CONNECTION" value="sync"/>
<server name="SESSION_DRIVER" value="array"/>
<server name="TELESCOPE_ENABLED" value="false"/>

I also have a test_create_user which passes correctly

public function test_create_user()
{
    $this->withoutExceptionHandling();

    $user = [
        'name' => Factory::create()->name(),
        'email' => Factory::create()->email(),
    ];

    $response = $this->post('/register', [
        'name' => $user['name'],
        'email' => $user['email'],
        'password' => Hash::make('123456'),
        'password_confirmation' => Hash::make('123456')
    ]);

    // $response->dumpHeaders();
    // $response->dump();

    $response->assertStatus(302);
}
question from:https://stackoverflow.com/questions/65864249/testing-login-scaffolding-in-laravel-with-phpunit

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your test_log_user() function is using the already hashed password for your user as the form password which, is then being hashed again before being checked against the value in the database.

The user factory sets the password field for a user to be a hash of the word password (unless you have changed this). For example:

public function definition()
{
    return [
        'name' => $this->faker->name,
        'email' => $this->faker->unique()->safeEmail,
        'email_verified_at' => now(),
        'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
        'remember_token' => Str::random(10),
    ];
}

So in your test_log_user() function:

$user = User::factory()->create();

Creates a new user in the database with $2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi as the value in the password field (a hash of the word password).

So the value of $user->password is not password, it is $2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi.

What you want to do is pass the plaintext password through:

$response = $this->post('/login', [
    'email' => $user->email,
    'password' => 'password' 
]);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...