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

pedroborges's avatar

Session missing 'errors' key in PHPUnit

I can't get the $this->assertSessionHasErrors(); assertion to work.

// The only trait I'm using is DatabaseTransactions

$this->visit('/signup');

$this->submitForm('Create my account', [
    'name'       => '',
    'email'      => 'pedro',
    'cellphone'  => 1698149,
    'password'   => 123,
    'password_confirmation' => 123
]);

$this->seePageIs('/signup');
$this->assertSessionHasErrors(); // this fails

If I $this->dump() the page it shows all the errors messages when the validation fails. It also works correctly in the browser. But when running phpunit all I get is:

Session missing key: errors
Failed asserting that false is true.

I also tried dumping $this->app['session.store'] in my test:

#attributes: array:4 [
  "_token" => "2hGrgYb0manQcPBpwi60BFozLnBBMAx0hYJVfEH3"
  "_previous" => array:1 [
    "url" => "http://localhost/signup"
  ]
  "flash" => array:2 [
    "old" => []
    "new" => []
  ]
  "_sf2_meta" => array:3 [
    "u" => 1449505334
    "c" => 1449505334
    "l" => "0"
  ]
]

This is the code where the form posts to in my routes.php:

// …

if ($validator->fails())
{
    return redirect('/signup')
                ->withInput()
                ->withErrors($validator);
}

// …

I'm using 5.1 fresh installed yesterday.

0 likes
14 replies
Max Y's avatar

I have exact same problem with you, but haven't figured out how to solve this...

pedroborges's avatar

I gave up trying to find a solution for this. I'm testing Laravel 5.2 now, I'll let you know if it works.

ejdelmonico's avatar

I've never used that assertion but, it looks like you may need to add an array of bindings to the assertion. ->assertSessionHasErrors($bindings = [], $format = null);

huglester's avatar

Maybe you should switch sessions to database in tests? because probably they are just array and not storing anything useful?

Javi's avatar

Well, I'm suffering the same behaviour. Laravel 5.1

Javi's avatar

Solved,

call $this->session()or Session::start() withing your test or your test setUp method.

1 like
Jmrtech's avatar

Anyone figure out a solution because I tried @Javi solution but still couldn't get it to work for me.

sinalco's avatar

I have the same problem too using Laravel 5.2 and haven't found any solution. Starting a new session in setUp or in the test method doesn't resolve the issue. I've also tested with different session drivers (other than array) without success.

Any idea @JeffreyWay ?

skliche's avatar

@nmarfurt Errors are only flashed to the session so when your assertion is executed they have already been removed. You can see that by displaying the session's contents: dd(session()->all());

If you put something into the session within your application before it fails to validate the input, e.g. session()->put('test','something'); you can see that it is still there. If you flash something to the session, e.g. session()->flash('test','something else'); you can see that it is no longer there.

1 like
sinalco's avatar

@skliche Thanks for your response, it makes sense.

Then it means that this assertation will always fail when used with a form, right? Not very intuitive I must say.

Do you know any other option to test that a form has been correctly submitted without validation errors? I know I could check that the page contains a message for each invalid field, but it doesn't seem optimal, especially with localized messages.

skliche's avatar

@nmarfurt Yes, it will always fail in such a situation.

After successfully submitting a form you are usually either redirected somewhere else or you should have any kind of visual indication of success (or failure). Both can easily be checked for. If you are concerned about localization just use trans() in your tests as well, e.g.

see(trans('forms.order.success'))

or in case of failure e.g.

see(trans('validation.confirmed', ['attribute' => 'password']))
2 likes
ChristosSymeou's avatar

I thought I'd post here for anybody having a similar problem, as I was having a similar issue. Typically when I want to test the validation of a form, I do $this->post->(route('endpoint for Controller handling the error). [data])->assertSessionHasErrors();

I did notice that if I do $this->json('post', route(), [data]) it fails - I need to use the $this->post method directly.

Please or to participate in this conversation.