Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test form request rules in Laravel 5?

I created a form request class and defined a bunch of rules. Now I would like to test these rules to see if the behaviour meets our expectations.

How could I write a test to accomplish that?

Many thanks in advance for your answers!

Update: more precisely, I would like to write a unit test that would check e.g. if a badly formatted email passes validation or not. The problem is that I don't know how to create a new instance of the Request with fake input in it.

like image 647
kant312 Avatar asked Apr 22 '15 10:04

kant312


3 Answers

Here's a full example of testing validation:

use App\Http\Requests\PostRequest;
use Illuminate\Routing\Redirector;
use Illuminate\Validation\ValidationException;

class PostRequestTest extends TestCase
{
    protected function newTestRequest($data = [])
    {
        $request = new PostRequest();

        $request->initialize($data);

        return $request
            ->setContainer($this->app)
            ->setRedirector($this->app->make(Redirector::class));
    }

    public function testValidationFailsWhenEmptyTitleIsGiven()
    {
        $this->expectException(ValidationException::class);

        $this->newTestRequest(['title' => ''])->validateWhenResolved();
    }
}
like image 198
Steve Bauman Avatar answered Oct 05 '22 17:10

Steve Bauman


The accepted answer tests both authorization and validation simultaneously. If you want to test these function separately then you can do this:

test rules():

$attributes = ['aa' => 'asd'];
$request = new MyRequest();
$rules = $request->rules();
$validator = Validator::make($attributes, $rules);
$fails = $validator->fails();
$this->assertEquals(false, $fails);

test authorize():

$user = factory(User::class)->create();
$this->actingAs($user);
$request = new MyRequest();
$request->setContainer($this->app);
$attributes = ['aa' => 'asd'];
$request->initialize([], $attributes);
$this->app->instance('request', $request);
$authorized = $request->authorize();
$this->assertEquals(true, $authorized);

You should create some helper methods in base class to keep the tests DRY.

like image 22
Martins Balodis Avatar answered Oct 16 '22 15:10

Martins Balodis


You need to have your form request class in the controller function, for example

public function store(MyRequest $request)

Now create HTML form and try to fill it with different values. If validation fails then you will get messages in session, if it succeeds then you get into the controller function.

When Unit testing then call the url and add the values for testing as array. Laravel doc says it can be done as

$response = $this->call($method, $uri, $parameters, $cookies, $files, $server, $content);
like image 2
Margus Pala Avatar answered Oct 16 '22 14:10

Margus Pala