@loren138 commented on Fri Jul 24 2015
I'm using the code from http://laravel.com/docs/5.1/testing#mocking-facades
IE
Cache::shouldReceive('get')
->once()
->with('key')
->andReturn('value');`
However, when I run this through PHPUnit I get the following error:
1) App\Models\GoogleAnalyticsTest::testCacheMohlerPopularUris
InvalidArgumentException: get() cannot be mocked as it a protected method and mocking
protected methods is not allowed for this mock
/Users/../Sites/resources/vendor/mockery/mockery/library/Mockery.php:670
/Users/../Sites/resources/vendor/mockery/mockery/library/Mockery.php:678
/Users/../Sites/resources/vendor/mockery/mockery/library/Mockery.php:629
/Users/../Sites/resources/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php:54
/Users/../Sites/resources/tests/Api/GoogleAnalyticsTest.php:22
The error makes perfect readable sense to me, but the problem is I need to mock the cache get function which happens to be exactly documented and it doesn't work...
@GrahamCampbell commented on Fri Jul 24 2015
You can't mock a manager class like that I'm afraid. The get call there is a __callStatic followed by a __call. You can only mock facades if the next call from __callStatic is a real method.
@loren138 commented on Fri Jul 24 2015
Once again, let me point out that this call is copied exactly from the documentation on mocking a facade http://laravel.com/docs/5.1/testing#mocking-facades and is the entire point of mocking them. At the very least, the docs should cover that this won't work. I shouldn't need to argue that this should work since Taylor in the docs says consider that you want to do this. Just to make this easier I'm copying the docs to here.
Mocking Facades (http://laravel.com/docs/5.1/testing#mocking-facades)
When testing, you may often want to mock a call to a Laravel facade. For example, consider the following controller action:
<?php
namespace App\Http\Controllers;
use Cache;
use Illuminate\Routing\Controller;
class UserController extends Controller
{
/**
* Show a list of all users of the application.
*
* @return Response
*/
public function index()
{
$value = Cache::get('key');
//
}
}
We can mock the call to the Cache facade by using the shouldReceive method, which will return an instance of a Mockery mock. Since facades are actually resolved and managed by the Laravel service container, they have much more testability than a typical static class. For example, let's mock our call to the Cache facade:
<?php
class FooTest extends TestCase
{
public function testGetIndex()
{
Cache::shouldReceive('get')
->once()
->with('key')
->andReturn('value');
$this->visit('/users')->see('value');
}
}
@tillkruss commented on Sun Sep 27 2015
@taylorotwell If this isn't working, maybe it should be removed from the docs?
@ctrlaltdylan commented on Thu Feb 11 2016
Why is this issue closed when there hasn't been a viable solution yet?