Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

temo's avatar
Level 2

Laravel unit test

Hello guys, test fails for some reason:

public function test_user_can_login_with_correct_credentials()
	{
		$user = User::factory()->create([
			'email'    => '[email protected]',
			'password' => Hash::make('password'),
		]);
		$this->actingAs($user);
		$response = $this->post('/login', [
			'email'    => $user->email,
			'password' => $user->password,
		]);
		$response->assertRedirect(route('worldwide.statistics'));
		$this->assertAuthenticatedAs($user);
	}
0 likes
37 replies
Tray2's avatar

Are you testing your own code or the code from Breeze or Jetstream?

If it's from one of those two, then you don't really need to test it, it's already tested.

Reaching 100% is hard for code you haven't written yourself.

1 like
Sinnbeck's avatar

If you show us exactly what lines isn't being covered we will have a greater chance of helping

Sinnbeck's avatar

@temo better to show them. As your code isn't formatted correctly I cannot count it.

temo's avatar
Level 2

@Sinnbeck

public function store(LoginRequest $request) { $validated = $request->validated();

	if (auth()->attempt($validated))
	{
		session()->regenerate();   -- 17
		$user = Auth::getProvider()->retrieveByCredentials($validated);
		Auth::login($user, $request->get('remember'));
		return redirect(route('worldwide.statistics'))->with('success', 'Welcome back!');  -- 23
	}
	return back()->withErrors(['failed' => __('texts.invalid_username_or_password')]);
}
Sinnbeck's avatar

@temo try this

public function test_user_can_login_with_correct_credentials()
{
	$user = User::factory()->create([
		'email'    => '[email protected]',
		'password' => Hash::make('password')
	]);

	//$this->actingAs($user); remove this 

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

	$response->assertRedirect(route('worldwide.statistics'));
	$this->assertAuthenticatedAs($user);
}

You are logging in, and then attempt to login.. But you are already logged in

In other words. $this->actingAs($user) logs in as the user before the request

1 like
temo's avatar
Level 2

@Sinnbeck

Got following error:

• Tests\Feature\ProjectsTest > user can login with correct credentials Failed asserting that two strings are equal.

at tests/Feature/ProjectsTest.php:174 170▕ 'email' => $user->email, 171▕ 'password' => $user->password, 172▕ ]); 173▕ ➜ 174▕ $response->assertRedirect(route('worldwide.statistics')); 175▕ $this->assertAuthenticatedAs($user); 176▕ } 177▕ 178▕ public function test_user_cannot_login_with_incorrect_password() --- Expected +++ Actual @@ @@ -'http://localhost/worldwide-statistics' +'http://localhost'

Tests: 1 failed, 1 risky, 20 passed Time: 2.11s

Sinnbeck's avatar

@temo can you format the code by adding ``` on the line before and after it. I'm having a hard time seeing where it failed

Sinnbeck's avatar

Try this change as well (updated my answer)

$user = User::factory()->create([
		'email'    => '[email protected]',
		'password' => Hash::make('password'),
	]); 
temo's avatar
Level 2

@Sinnbeck

• Tests\Feature\ProjectsTest > user can login with correct credentials Failed asserting that two strings are equal.

at tests/Feature/ProjectsTest.php:171

    167▕ 			'email'    => $user->email,
    168▕ 			'password' => $user->password,
    169▕ 		]);
    170▕ 
  ➜ 171▕ 		$response->assertRedirect(route('worldwide.statistics'));
    172▕ 		$this->assertAuthenticatedAs($user);
    173▕ 	}
    174▕ 
    175▕ 	public function test_user_cannot_login_with_incorrect_password()
  --- Expected
  +++ Actual
  @@ @@
  -'http://localhost/worldwide-statistics'
  +'http://localhost'

Tests: 1 failed, 1 risky, 21 passed Time: 1.63s

Sinnbeck's avatar

@temo ah sorry. You shouldn't send the hash password to the route. Fixed my answer

Sinnbeck's avatar

@temo can you login normally? I haven't checked your code, only test

Can you show what you have now?

temo's avatar
Level 2

@Sinnbeck Yes I can login in web and other tests are working well too.

• Tests\Feature\ProjectsTest > user can login with correct credentials Failed asserting that two strings are equal.

  at tests/Feature/ProjectsTest.php:171
    167▕ 			'email'    => $user->email,
    168▕ 			'password' => $user->password,
    169▕ 		]);
    170▕ 
  ➜ 171▕ 		$response->assertRedirect(route('worldwide.statistics'));
    172▕ 		$this->assertAuthenticatedAs($user);
    173▕ 	}
    174▕ 
    175▕ 	public function test_user_cannot_login_with_incorrect_password()
  --- Expected
  +++ Actual
  @@ @@
  -'http://localhost/worldwide-statistics'
  +'http://localhost'

Tests: 1 failed, 1 risky, 21 passed Time: 1.65s

Sinnbeck's avatar

@temo yeah the other tests aren't trying to sign in. The problem is that your test fails to sign in. Can you show the test? And please format it like Ive shown earlier

temo's avatar
Level 2

@Sinnbeck Sure, you mean this one?

	{
		$user = User::factory()->create([
			'email'    => '[email protected]',
			'password' => Hash::make('password'),
		]);

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

		$response->assertRedirect(route('worldwide.statistics'));
		$this->assertAuthenticatedAs($user);
	}
temo's avatar
Level 2

@Sinnbeck And sorry if i am doing something wrong, first time posting here. <code> is that what you meant?

temo's avatar
Level 2

@Sinnbeck So test works if I use actingAs($user), but I cant get 100% coverage for some reason:

public function test_user_can_login_with_correct_credentials()
	{
		$user = User::factory()->create([
			'email'    => '[email protected]',
			'password' => Hash::make('password'),
		]);
		$this->actingAs($user);

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

		$response->assertRedirect(route('worldwide.statistics'));
		$this->assertAuthenticatedAs($user);
	}
``` .

Http/Controllers/SessionController 17..23 ................................................................................................................... 55.6 %


And here's controller: 

public function store(LoginRequest $request) { $validated = $request->validated();

	if (auth()->attempt($validated))
	{
		session()->regenerate();

		$user = Auth::getProvider()->retrieveByCredentials($validated);

		Auth::login($user, $request->get('remember'));

		return redirect(route('worldwide.statistics'))->with('success', 'Welcome back!');
	}

	return back()->withErrors(['failed' => __('texts.invalid_username_or_password')]);
}
public function destroy(): RedirectResponse
{
	auth()->logout();
	return redirect(route('home'));
}
Sinnbeck's avatar

@temo if you use acting as you are skipping the authentication part completely.

Maybe show the login form so we can compare?

temo's avatar
Level 2

@Sinnbeck Login form:

  <form method="POST" action="{{route('login.store')}}" >
                    @csrf
                    <x-form.input
                        name="{{__('texts.enter_email')}}"
                        input="email"
                        placeholder="{{__('texts.enter_email')}}"/>
                    <x-form.input
                        name="{{__('texts.password')}}"
                        input="password"
                        placeholder="{{__('texts.fill_in_password')}}"/>
                    <div class="flex justify-between mb-3">
                        <x-form.checkbox/>
                        <a href="{{route('password.request')}}"
                           class="text-blue-600">
                            {{__('texts.forgot_password')}}?
                        </a>
                    </div>
                    <x-form.button>{{__('texts.log_in')}}</x-form.button>
                </form>

Sinnbeck's avatar

@temo the name of the input name="{{__('texts.enter_email')}}" ? That sounds strange!

Can you add dd($validated); and try to login normally. What do you get?

temo's avatar
Level 2

@Sinnbeck Thing is that user need to verify email when registered,in order to login, do I need to include that in test function too?

Sinnbeck's avatar

@temo ah then you need to validate it

$user = User::factory()->create([
		'email'    => '[email protected]',
		'password' => Hash::make('password'), 
        'validated_at' => now()->subDay()
	]);
temo's avatar
Level 2

@Sinnbeck Still getting same error:

Failed asserting that two strings are equal.

  at tests/Feature/ProjectsTest.php:311
    307▕ 			'email'    => $user->email,
    308▕ 			'password' => $user->password,
    309▕ 		]);
    310▕ 
  ➜ 311▕ 		$response->assertRedirect(route('worldwide.statistics'));
    312▕ 		$this->assertAuthenticatedAs($user);
    313▕ 	}
    314▕ 
    315▕ //	public function test_something()
  --- Expected
  +++ Actual
  @@ @@
  -'http://localhost/worldwide-statistics'
  +'http://localhost'

Tests: 1 failed, 22 passed Time: 1.63s

Sinnbeck's avatar

@temo you need to figure out why it isn't logging in.

My guess is that you hit this

return back()->withErrors(['failed' => __('texts.invalid_username_or_password')]);

Use dd() for debugging

temo's avatar
Level 2

@Sinnbeck I hardcoded password and it works for some reason

	$user = User::factory()->create([
			'email'             => '[email protected]',
			'password'          => 'password',
			'email_verified_at' => now()->subDay(),
		]);

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

@temo that's weird. Aren't your passwords hashed in the database?

Sinnbeck's avatar
Sinnbeck
Best Answer
Level 102

@temo maybe you have a mutator on the user model that hashes them?

temo's avatar
Level 2

@Sinnbeck I guess yes, error was caused by hashing the password two times

public function setPasswordAttribute($password)
	{
		$this->attributes['password'] = bcrypt($password);
	}
parapente's avatar

You are missing a test with invalid credentials to hit the line

return back()->withErrors(['failed' => __('texts.invalid_username_or_password')]);
temo's avatar
Level 2

@parapente

forgot to mention this one

public function test_user_cannot_login_with_incorrect_password()
{
	$user = User::factory()->create([
		'email'    => '[email protected]',
		'password' => bcrypt('i-love-laravel'),
	]);
	$response = $this->from('/')->post('/login', [
		'email'    => $user->email,
		'password' => 'invalid-password',
	]);
	$response->assertRedirect('/');
	$response->assertSessionHasErrors();
	$this->assertGuest();
}

Please or to participate in this conversation.