5

I'm trying to test a method from a class which contains a method using the request() helper from Laravel. This is the method:

Category class

public function getCanonicalUrl()
{
    return preg_match('/\/sale\/./', request()->getRequestUri())
         ? ''
         : url($this->getUrlKey());
}

The test should make this helper to catch properly the URI when doing getRequestUri() but it's actually returning an empty string. This is one of the thousand tries that I gave to the test.

Test

public function testCanonical()
{
    // ...

    $requestMock = Mockery::mock(Request::class)
      ->shouldReceive('getRequestUri')
      ->andReturn('/sale/random-string');

    $this->app->instance(Request::class, $requestMock);

    // ...
}

Any ideas of how this could be achieved? Thanks in advance.

therealbigpepe
  • 1,489
  • 2
  • 16
  • 23

2 Answers2

3

You should not mock the Request facade. Instead, pass the input you desire into the HTTP helper methods such as get and post when running your test.

https://laravel.com/docs/5.5/mocking#mocking-facades

Alexey Mezenin
  • 158,981
  • 26
  • 290
  • 279
0

Per https://stackoverflow.com/a/61903688/135114, if

  1. your function under test takes a $request argument, and
  2. you don't need to do funky stuff to the Request—real route paths are good enough for you

... 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));
}
Daryn
  • 4,791
  • 4
  • 39
  • 52