Testing Form Request Validation in Laravel

I recently got stuck writing a test for a Controller which uses a custom form request for validation and authorization. Though the form request worked correctly for real requests in the browser, it was being ignored from the Feature test. In other words the Controller action would run even with invalid test input and even when the form request was hard-coded to specifically block authorization.

Incorrect Approach

I had been creating the form request, instantiating the Controller I wanted to test and sending the request. This bypassed the checks, presumably because the middleware that triggers validation isn’t run in this context.

function test_invalid_request()
{
  $request = CafeStoreRequest::create('cafe', 'POST', ['cafe_name' => '']); //should fail
  $controller = new App\Http\Controllers\CafeController();
  $response = $controller->store($request);

  $response->assertSessionHasErrors(['cafe_name']);
}

What Worked

Instead of manually creating a controller, I needed to route the request through the HTTP layer so that the middleware would do its thing and trigger the appropriate error.

function test_invalid_input()
{
  $response = $this->post(route('cafe.store', ['cafe_name' => '']));
  $response->assertSessionHasErrors(['cafe_name']);
}

Leave a Reply

Your email address will not be published. Required fields are marked *