Mock Request Dependency in Laravel
Arie Visser • October 25, 2023
laravel php testingIn 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.