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

booni3's avatar

Inject user into form request - testing Autorization

I have feature tests hitting the post route to my form request and these all work fine.

However, I have some quite complicated authorization logic that I would like to test in isolation.

I am already doing something similar for some validation rules as follows:

public function setUp(): void
{
    parent::setUp();

    $this->subject = new \App\Http\Requests\OrderStoreRequest();

    $this->rules = $this->subject->rules();

    $this->validator = $this->app['validator'];
}

public function test_fields_are_valid()
{
    $this->assertTrue($this->validateField('country_code', 'GB'));
    $this->assertFalse($this->validateField('country_code', 'ZZ'));
}

I would now like to test the authorization method, but cannot work out how to inject a mock user into the form request. This does not work...

public function testAuthorize()
{
    $this
        ->actingAs(\factory(User::class)->create())
        ->assertTrue($this->subject->authorize());
}

Would much appricate any ideas on how this can be done with unit tests.

0 likes
7 replies
booni3's avatar

I have already got some feature tests setup posting to the endpoint. That is all fine.

What I am trying to get around, is creating 10 - 20 separate feature tests to check every configuration of my user and permission rules. This request, in particular, is quite complicated as depending on the kind of user will change the type of data we can accept. I have admin users and normal users and each has related roles and permissions.

I want to be able to test all of these quickly through a unit test that does not hit the database.

I am seeing this testing as:

  1. Feature tests that post to the endpoints: Used to check everything is wired up correctly and valid data results in the correct new rows in my database.

  2. Unit tests: ideally not hitting the database and can check the more detailed implementation of validation and authorization of the request.

Nakov's avatar

@lambooni I don't see how what you explained in number 2 is a unit test, when you need to check the authorization and validation, which again will call methods from the core of the framework.

I am sorry, but my opinion stays on that you just need integration/feature tests for the Form request, testing different scenarios for the input that can be entered and check if the validation passes or does not.

I cannot wrap my head around your second scenario.

booni3's avatar

This is a simple example, that helps to explain my testing methodology:

https://jasonmccreary.me/articles/test-validation-laravel-form-request-assertion/

I also have run through Jasons testing course and found it quite useful, but it does not go into great levels of detail. Maybe these testing opinions are not for everyone, but in summary to validate a form request:

  1. Create a feature/integration test posting to the endpoint. Ensure 200 is returned and the database is populated with the correct data.

  2. Create a unit test/s that ensure the finer details of the form request are working. In the example, he keeps it very simple (almost like a spell checker), but it is quite easy to extrapolate this out a little to test more compex logic in both the authorize method as well as any individual validation rules. I agree we would not ever want to test the laravel built-in rules but there may be more complex custom rules or closures that there would be value in testing.

Nakov's avatar

@lambooni I agree with this

may be more complex custom rules or closures that there would be value in testing

Then you will test your custom rule. But not the form request in a unit test.

And if you read in his article, he does not involved an authenticated user to test the form request. And his form request is not shown, so he might just returns true from the authorize method.

booni3's avatar
booni3
OP
Best Answer
Level 3

So I realise now that a unit test, may not be the best way to test this at all... but in answer to the original question:

'How to inject the user into form request, so that you can retrieve the user with $this->user()

$this->subject->setUserResolver(function () use($user) {
   return $user;
});
Spikerok's avatar

To test authorize you'd want to test a policy (or a relevant class) instead.

i.e.

class  MyPolicy 
{
	public function insert(User $user) {
		// ...
	}
}	

You can unit test a policy by mocking model data, no need for DB connection.

i.e.

public function testInsertPermission()
{
	//  initiate a model with  dummy data
	$dummyData =  ['name' => 'Joe Doe'];
	$mockedUser = new User($dummyData);

	// or just mock it
	$mockedUser =  Mockery::mock(User::class);
	$mockedUser...

	$actual  = app(MyPolicy::class)->insert($mockedUser);

	$this->assertEquals(true,  $actual);
}

Then, when unit testing the form request you'd want to check that the policy within authorized was called, i.e.

$this->mock(MyPolicy::class, function (MockInterface $mock) {
    $mock->shouldReceive('insert')->once();
});

You can also perform the same logic within FormRequest without a need for a separate class, but it may look untidy from the architecture point of view.

Please or to participate in this conversation.