I'm trying to test a function that depends on
$request->all();
in a method. How do I mock the Request class so $request->all();
returns
['includes' => ['some_val','another_val']
in tests?
I'm trying to test a function that depends on
$request->all();
in a method. How do I mock the Request class so $request->all();
returns
['includes' => ['some_val','another_val']
in tests?
I recommend you to use mockery/mockery
. You will have to do this:
In your test method do:
app()->bind(
\Illuminate\Http\Request::class,
function () {
$mock = \Mockery::mock(\Illuminate\Http\Request::class)->makePartial();
$mock->shouldReceive('all')
->andReturn(['includes' => ['some_val', 'another_val']]);
return $mock;
}
);
What you are doing there is:
mock
to the Request
, so when you do yourMethod(Request $request)
it will instantiate your mock instead of the real class\Mockery::mock(CLASS)->makePartial();
will first create a mock of that class, and then (makePartial()
) will allow you to use other non-mocked methods (use real methods) so any method you didn't mock will run real codeshouldReceive
will allow the mocked class to mock that method (argument of shouldReceive
), so we are mocking all
method and returning your desired value, in this case, the array you postedAs @devk stated, Laravel does not recommend mocking Request
class, so don't do it, but if you need to mock any other object, you can use the code above and it will perfectly work.
Per https://stackoverflow.com/a/61903688/135114, if
$request
argument,... then you don't need to "mock" a Request (as in, mockery),
you can just create a Request
and pass it, e.g.
public function test_myFunc_condition_expectedResult() {
...
$mockRequest = Request::create('/path/that/I_want', 'GET');
$this->assertTrue($myClass->myFuncThat($mockRequest));
}
As stated by devk, don't mock the request. But Laravel allows you to build an actual request and then call your controller in your test like this:
public function testPostRequest() {
$response = $this->post(
'/my-custom-route',
['includes' => ['some_val','another_val']]
);
}
This works well, for a mock or you can do as above with the partial depending on if you want the request object to pass around or inspect
/** @var \Illuminate\Http\Request|\Mockery\MockInterface */
$request = $this->mock(Request::class, function (MockInterface $mock) {
$mock->shouldReceive('all')
->once()
->andReturn([
'includes' => [
'some_val', 'another_val',
],
]);
});