Skip to content
Advertisement

assertRedirect causing output of email already exists – PHP Testing

So my test case in laravel is the following:

  public function test_user_can_sign_up_using_the_sign_up_form()
    {
        $user = User::factory()->create();

        $user = [
            'username' => $user->username,
            'email' => $user->email,
            'password' => $user->password,
            'password_confirmation' => $user->password,
            'dob' => $user->dob
        ];

        $response = $this->post('/register', $user);

        // Removes password confirmation from array
        array_splice($user, 3);

        $this->assertDatabaseHas('users', $user);

        $response->assertRedirect('/home');

    }

This line:

$response->assertRedirect('/home');

is causing the test to fail and get an output of ‘The email has already been taken’ Why is this the case? I want to check upon sign up, the user is directed to the home page which it does but my test fails.

The user is being created in the database so that part works fine.

UserFactory:

<?php

namespace DatabaseFactories;

use IlluminateDatabaseEloquentFactoriesFactory;
use IlluminateSupportStr;

/**
 * @extends IlluminateDatabaseEloquentFactoriesFactory<AppModelsUser>
 */
class UserFactory extends Factory
{
    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition()
    {
        return [
            'username' => fake()->name(),
            'email' => fake()->unique()->safeEmail(),
            'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
            'dob' => fake()->date(),
        ];
    }

    /**
     * Indicate that the model's email address should be unverified.
     *
     * @return static
     */
    public function unverified()
    {
        return $this->state(fn (array $attributes) => [
            'email_verified_at' => null,
        ]);
    }
}

Advertisement

Answer

Okay I will explain your test case to you.

You are testing a register feature of your app.

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

$user = [
    'username' => $user->username,
    'email' => $user->email,
    'password' => $user->password,
    'password_confirmation' => $user->password,
    'dob' => $user->dob
];

$response = $this->post('/register', $user);

this block of code is wrong because you are using the data of a User already inside the database to create an account. So it will naturally fails since the data is already inside the database the moment you call the User::factory()->create().

So instead of that you should pass a data that looks like you are the one registering.Remove the User::factory()->create() then replace the array $user with hard coded data or use the fake() helper.

$user = [
    'username' => fake()->userName(),
    'email' => fake()->unique()->safeEmail(),
    'password' => 'password',
    'password_confirmation' => 'password',
    'dob' => 'asldkjasd'
];

$response = $this->post('/register', $user);

$response->assertValid();

$this->assertDatabaseHas('users', [
    'email' => $user['email'],
]);

$response->assertRedirect('/home');
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement