Mock Request Dependency in Laravel

Arie Visser • October 25, 2023

laravel php testing

In Laravel it is seen as good practice to dependency inject the Illuminuate\Http\Request object in your methods when possible, instead of using the request() helper. One of the benefits of dependency injection is that it makes it possible to mock the dependency when testing.

In this article I will show you how you can mock the Request object in Laravel.

Mock the Request object in Laravel

Should you ever mock the Request object in your tests? It is recommended in the Laravel documentation to use the HTTP testing methods when possible. This will of course also create a request with a Request object, and you will have the ability to set most of the values you need.

However, sometimes it can help to mock a request when testing. For example, when you want to test only one specific method that injects the Request object, and not the whole request cycle.

Another use case I had was with the Livewire::test method, in Livewire 2. When using this method, a random REQUEST_URI parameter is generated. As a result, the $request->route()->uri() method returned something like "testing-livewire/RgSVitlQnqYK9rT3nG7A", while I needed a hard-coded value like "items-for-sale" in order for the page to load.

In such cases, you can mock the Request object like this:

use App\Http\Livewire\SalePage;
use Illuminate\Http\Request;
use Livewire\Livewire;
use Mockery\MockInterface;

...

public function run_test(): void
{
    $this->mock(Request::class, function (MockInterface $mock): void {
    $mock->shouldReceive('route')
        ->andReturn(new class() {
                public function uri(): string
                {
                    return 'items-for-sale';
                }
            });
    });

    Livewire::test(SalePage::class)
            ->assertViewIs('livewire.sale-page');
}

When calling the $request->route()->uri() in the method that injects the Request object, you will see the "items-for-sale" value.

In my case, this was the mount method in the Livewire component:

use Illuminate\Http\Request;

...

public function mount(Request $request)
{
    $slug = $request->route()?->uri();
}

In this way it is possible to set all values that are needed to make your tests pass.