A facade root has not been set - laravel

Laravel 6.5
Laravel Browser Kit ^5.1
I am creating my own packages for something I building and one is causing the issue at hand: A facade root has not been set. when I run my tests.
This is routes file App\Game\routes\web.php:
<?php
use Illuminate\Support\Facades\Route;
// Core routes for the game related stuff:
Route::get('/game', ['as' => 'game', 'uses' => 'GameController#game']);
Pretty basic, nothing here that should stand out. So how do we register these:
<?php
namespace App\Game\Providers;
use Illuminate\Routing\Router;
use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
class RoutesProvider extends ServiceProvider
{
protected $namespace = 'App\Game\Controllers';
public function boot()
{
parent::boot();
}
public function map()
{
$this->mapWebRoutes();
}
protected function mapWebRoutes()
{
Route::middleware('web')
->namespace($this->namespace)
->group(__DIR__.'/../routes/web.php');
}
}
Again nothing insane, if we addd this to the config/app.php and run php artisan route:list we see:
You can see the game route above. so now lets run our tests, make sure nothings breaking ...
composer phpunit
> ./vendor/bin/phpunit --coverage-html=./test-coverage
PHPUnit 8.4.3 by Sebastian Bergmann and contributors.
Fatal error: Uncaught RuntimeException: A facade root has not been set. in /Users/xxxx/Documents/xxxx/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php:242
Stack trace:
#0 /Users/xxxx/Documents/xxxx/app/Game/routes/web.php(5): Illuminate\Support\Facades\Facade::__callStatic('get', Array)
#1 /Users/xxxx/Documents/xxxx/vendor/phpunit/php-code-coverage/src/CodeCoverage.php(955): include_once('/Users/adambala...')
#2 /Users/xxxx/Documents/xxxx/vendor/phpunit/php-code-coverage/src/CodeCoverage.php(239): SebastianBergmann\CodeCoverage\CodeCoverage->initializeData()
#3 /Users/xxxx/Documents/xxxx/vendor/phpunit/phpunit/src/Framework/TestResult.php(646): SebastianBergmann\CodeCoverage\CodeCoverage->start(Object(Tests\Unit\xxxx\BaseStatValueTest))
#4 /Users/xxxx/Documents/xxxx/vendor/phpunit/phpunit/src/Framework/TestCase.php(752): PHPUnit\Framework\TestResult->run(Object(Tests\Unit\xxxx\BaseStatValueTest))
#5 /Users/xxxx/Documents/xxxx/vendor/phpunit/phpunit/src/Framewor in /Users/xxxx/Documents/xxxx/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php on line 242
PHP Fatal error: Uncaught RuntimeException: A facade root has not been set. in /Users/xxxx/Documents/xxxx/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php:242
Stack trace:
#0 /Users/xxxx/Documents/xxxx/app/Game/routes/web.php(5): Illuminate\Support\Facades\Facade::__callStatic('get', Array)
#1 /Users/xxxx/Documents/xxxx/vendor/phpunit/php-code-coverage/src/CodeCoverage.php(955): include_once('/Users/adambala...')
#2 /Users/xxxx/Documents/xxxx/vendor/phpunit/php-code-coverage/src/CodeCoverage.php(239): SebastianBergmann\CodeCoverage\CodeCoverage->initializeData()
#3 /Users/xxxx/Documents/xxxx/vendor/phpunit/phpunit/src/Framework/TestResult.php(646): SebastianBergmann\CodeCoverage\CodeCoverage->start(Object(Tests\Unit\xxxx\BaseStatValueTest))
#4 /Users/xxxx/Documents/xxxx/vendor/phpunit/phpunit/src/Framework/TestCase.php(752): PHPUnit\Framework\TestResult->run(Object(Tests\Unit\xxxx\BaseStatValueTest))
#5 /Users/xxxx/Documents/xxxx/vendor/phpunit/phpunit/src/Framewor in /Users/xxxx/Documents/xxxx/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php on line 242
Its all caused by that web.php routes file when it tries to create the route doing: Route::get(....). From my understanding router does not exist in app container when the app boots up for test.
I have tried calling setUp in my test classes, and calling it's parent. But still I get the error.
I have never encountered this before and nothing o the internet is helping me. Any ideas as to why I am getting this error?

Exclude the routes folder on phpunit coverage tests:
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./app</directory>
<exclude>
<directory>./app/Game/routes</directory>
</exclude>
</whitelist>
</filter>

Related

Laravel 8 - Route cannot find controllers: Target class [Auth\LoginController] does not exist [duplicate]

This question already has answers here:
Error “Target class controller does not exist” when using Laravel 8
(27 answers)
Closed 2 years ago.
I went to take Laravel 8 for a spin today, but it seems the Route facade cannot find controllers anymore.
The route /home gives me this error:
Target class [HomeController] does not exist.
I get a similar error when I run: php artisan route:list
Illuminate\Contracts\Container\BindingResolutionException
Target class [Auth\LoginController] does not exist.
at C:\...\vendor\laravel\framework\src\Illuminate\Container\Container.php:811
811 throw new BindingResolutionException("Target class [$concrete] does not exist.", 0, $e);
Thanks to lagbox, I ended up adding namespace('App\Http\Controllers') to the web route in RouteServiceProvider boot method:
public function boot()
{
$this->configureRateLimiting();
$this->routes(function () {
Route::middleware('web')
->namespace('App\Http\Controllers')
->group(base_path('routes/web.php'));
That did the trick for me. Any better solutions would be most welcome.
If this is a fresh install of Laravel 8, there is no namepsace defined in the RouteServiceProvider to be applied to the your routes. You can try to wrap the Auth::routes() call in a route group that declares the namespace App\Http\Controllers, or go about this in a different way. (assuming you have installed laravel/ui)
Route::namespace('App\Http\Controllers')->group(function () {
Auth::routes();
});
If you want to know how to deal with the lack of namespace being defined for your routes:
https://stackoverflow.com/a/63808132/2109233

Laravel 5.6 - Uncaught RuntimeException: A facade root has not been set

I am getting following error when I try to use Illuminate\Http\Request in my class.
Error:
PHP Fatal error: Uncaught RuntimeException: A facade root has not been set. in /home/sasha/Documents/OffProjects/vetnearme/vetnearme/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php:218
Stack trace:
#0 /home/sasha/Documents/OffProjects/vetnearme/vetnearme/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php(396): Illuminate\Support\Facades\Facade::__callStatic('replaceNamespac...', Array)
#1 /home/sasha/Documents/OffProjects/vetnearme/vetnearme/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php(373): Illuminate\Foundation\Exceptions\Handler->registerErrorViewPaths()
#2 /home/sasha/Documents/OffProjects/vetnearme/vetnearme/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php(288): Illuminate\Foundation\Exceptions\Handler->renderHttpException(Object(Symfony\Component\HttpKernel\Exception\HttpException))
#3 /home/sasha/Documents/OffProjects/vetnearme/vetnearme/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php(187): Illumina in /home/sasha/Documents/OffProjects/vetnearme/vetnearme/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php on line 218
The class in question:
namespace App\App\Components;
use Illuminate\Http\Request;
/**
* This class will be used to build menu for admin panel based on the user role
*/
class AdminPanelMenu {
static function menu(Request $request){
$user = $request->user();
if($user->hasRole['super_admin'])
return self::superAdmin();
if($user->hasRole['admin'])
return self::admin();
if($user->hasRole['user'])
return self::user();
return [];
}
private static function superAdmin()
{
return [
'MAIN NAVIGATION',
];
}
private static function admin()
{
return [
'MAIN NAVIGATION',
];
}
private static function user()
{
return [
'MAIN NAVIGATION',
];
}
}
What am I doing wrong here?
You need to create a new app container and then bind it to the Facade.
use \Illuminate\Container\Container as Container;
use \Illuminate\Support\Facades\Facade as Facade;
/**
* Setup a new app instance container
*
* #var Illuminate\Container\Container
*/
$app = new Container();
$app->singleton('app', 'Illuminate\Container\Container');
/**
* Set $app as FacadeApplication handler
*/
Facade::setFacadeApplication($app);
in lumen:
bootstrap/app.php
$app->withFacades();
Good luck!
I know this is old but maybe it will help someone. I ran into this problem after I was fiddling with my app/config.php file. I added some options and accidentally put a semi-colon instead of a comma after it.
I had:
'vapid_public_key' => env('VAPID_PUBLIC_KEY'); <--- offending semi-colon
'vapid_private_key' => env('VAPID_PRIVATE_KEY'),
Changed it to the proper comma and everything works as expected.
Really late but hopefully can help someone else. I found the easiest solution to this error was just to change the route (ie from /post to /posts) of the page that this error appears. And don't forget to change anywhere that has direct links to it.
I think the problem is that Laravel is confusing scope resolution to facade error. check your code so make sure you do not have any static variable not existing in a class. E.g if you have a PHP class like;
<?php
class StaticExample
{
public const EXAM = 'exam';
}
?>
then you try to call a non-existing const StaticExample::EXAMS. Laravel will give you the above error which makes no sense because it's very difficult to trace. No error in the logs and you're lost.
My solution is to use an editor like PHPStorm that will point out your development errors. Another way is that you should check your scope resolutions very well.

JWTGenerateCommand::handle() does not exist

I am using Laravel 5.4 and JWT Auth Library for user authentication in API development. After installation while i am running php artisan jwt:generate then it throws me error of
Method Tymon\JWTAuth\Commands\JWTGenerateCommand::handle() does not exist
Any idea what i am missing ?
This error generally display when you install jwt package in laravel 5.5 version. then after you set service providers and run following command.
php artisan jwt:generate
then you seen this error message in terminal.
how to resolve it? simple follow this step
Step - 1 Re-install package
composer require tymon/jwt-auth:dev-develop --prefer-source
or the following is a new release package use laravel 6.X
composer require tymon/jwt-auth:1.0.*
in this developement version this errors fixed.
Step - 2 Set Service Provider
'providers' => [
....
Tymon\JWTAuth\Providers\JWTAuthServiceProvider::class to
Tymon\JWTAuth\Providers\LaravelServiceProvider::class
],
Step - 3 Generate key
php artisan jwt:secret
i found this solution from here https://laravelcode.com/post/method-tymonjwtauthcommandsjwtgeneratecommandhandle-does-not-exist
Go to JWTGenerateCommand.php file located in vendor/tymon/src/Commands and paste this method
public function handle() { $this->fire(); }
It's never a great idea to change anything in the vendor folder but the there's two ways to deal with this ...
Generate a random string yourself and just change the value in the JWT config file.
Go to Tymon\JWTAuth\Commands\JWTGenerateCommand and change the fire method to handle.
go to given file path
vendor/tymon/jwt-auth/src/Commands/JWTGenerateCommand.php
change function name
public function fire() to public function handle()
run command:
php artisan jwt:generate
I'm publishing this answer because I have crash in this error more than one time.
The only solution I found that it works with Laravel 5.6 is the following:
Add "tymon/jwt-auth": "1.0.0-rc.1" to composer.json and run composer update
Open config/app.php and add the following:
config/app.php:
'providers' => [
/*
* JWT Service Provider...
*/
Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
],
'aliases' => [
'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class,
],
Execute:
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
Finally, execute: php artisan jwt:secret
After all that, when I hit my endpoint for login I got the following exception:
Class Tymon\JWTAuth\Providers\JWT\NamshiAdapter does not exist
This was fixed by:
Open config/jwt.php and change the following:
config/jwt.php:
'jwt' => Tymon\JWTAuth\Providers\JWT\Namshi::class,
'auth' => Tymon\JWTAuth\Providers\Auth\Illuminate::class,
'storage' => Tymon\JWTAuth\Providers\Storage\Illuminate::class,
Finally, note that in order to work your User model should be defined as follows:
class User extends Authenticatable implements JWTSubject
{
...
public function getJWTIdentifier()
{
return $this->getKey();
}
public function getJWTCustomClaims()
{
return [];
}
...
}
I can advise one solution. Go to JWTGenerateCommand.php file located in vendor/tymon/src/Commands and paste this part of code public function handle() { $this->fire(); }
I know this is not an elegant solution, but it works. I hope this might help until official fix arrive.
see here for more info
Change fire() function to handle() in this path
vendor/tymon/jwt-auth/src/commands/JWTGenerateCommand.php
In the file path: /vendor/tymon/jwt-auth/src/Commands/JWTGenerateCommand.php
Add public function
public function handle()
{
$this->fire();
}

Laravel5 and PHPUnit with code coverage: Segmentation fault after Authentication

I use PHPUnit with code coverage on my Laravel 5 project on MAC OS X 10.9.5. I wrote a test class for a client profile page as follows.
<?php
use Illuminate\Foundation\Testing\DatabaseMigrations;
class MinimalViewTest extends TestCase
{
use DatabaseMigrations;
public function testWithSegFault()
{
...
$this->actingAs($userAuthorized)
->visit('/clients/profile/x11')
->visit('/clients/profile/' . $randomUser->id);
}
}
The test visits two different pages as an authorized user. The first visit to /clients/profile/x11 succeeds. However, the second visit ends in a segmentation fault.
$ vendor/bin/phpunit -v tests/MinimalViewTest.php
PHPUnit 5.0.10 by Sebastian Bergmann and contributors.
Runtime: PHP 7.0.0 with Xdebug 2.4.0
Configuration: /.../phpunit.xml
Segmentation fault: 11
If I call PHPUnit with no code coverage, the test succeeds.
$ vendor/bin/phpunit -v tests/MinimalViewTest.php --no-coverage
PHPUnit 5.0.10 by Sebastian Bergmann and contributors.
Runtime: PHP 7.0.0 with Xdebug 2.4.0
Configuration: /.../phpunit.xml
. 1 / 1 (100%)
Time: 1.71 seconds, Memory: 16.00Mb
OK (1 test, 3 assertions)
Besides the authentication provided by Laravel 5, I use my own middleware to determine the user group.
Route::group(['middleware' => ['web', 'auth', 'usergroup'], 'groups' => ['admin', 'orgateam']], function ()
{
Route::get('/clients/profile/{clientsId}', ['as' => 'clientsProfileByClientId', 'uses' => 'ClientsController#profileByClientId']);
});
The middleware I use is as follows.
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth as Auth;
class UserGroupMiddleware
{
public function handle($request, Closure $next)
{
return $next($request);
}
}
I could track the issue down to the call $next($request) that raises the segmentation fault. However, I am able to var_dump both objects $next and $request with no problem.
I used gdb to find more hints on why the segmentation fault occurs. It points me to
Program received signal SIGSEGV, Segmentation fault.
0x00007fff88a7fd13 in _platform_strcmp ()
from /usr/lib/system/libsystem_platform.dylib
What is happening here precisely? Is there really an issue with the Authentication of Laravel 5 and PHPUnit code coverage? I would really like to use code coverage along with PHPUnit.

Laravel 4 model unit test with Codeception - Class 'Eloquent' not found

I'm trying to use Codeception to run my Laravel 4 unit tests.
Running a test for a simple class with no dependencies works fine. But when I instantiate a model which depends on Eloquent, I get this fatal error:
PHP Fatal error: Class 'Eloquent' not found in /var/www/project/app/models/Role.php on line 4
Unit test:
<?php
use Codeception\Util\Stub;
class TestModel extends \Codeception\TestCase\Test
{
public function testExample()
{
$role = new Role;
$role->name = 'superuser';
$this->assertEquals('superuser', $role->name);
}
}
Model:
<?php
class Role extends Eloquent
{
public function users()
{
return $this->belongsToMany('User');
}
}
Project structure:
I'm running vendor/bin/codecept run unit from the project root, with this file structure:
/project
codeception.yml
/vendor/bin/codecept
/app
/tests
unit.suite.yml
/unit
ExampleTest.php
/models
Role.php
...etc
What am I doing wrong?
By looking at the Codeception L4 sample app, I was able to see how to bootstrap the autoload to resolve this issue, by adding these lines to project/app/tests/_boostrap.php:
include __DIR__.'/../../vendor/autoload.php';
$app = require_once __DIR__.'/../../bootstrap/start.php';
\Codeception\Util\Autoload::registerSuffix('Page', __DIR__.DIRECTORY_SEPARATOR.'_pages');
Edit: when upgrading from Laravel 4.0 to 4.1, it is also necessary to add an extra line:
$app->boot();
I'm probably late to the party, but if you don't need the codecept stuff. You should be extending laravel's implementation of PHPUnit_Framework_TestCase called just TestCase. Like this:
class TestModel extends TestCase {
}
The answer to this question is a little outdated now. With Laravel 5 I got the same error (Class 'Eloquent' not found...) and solved it by copying the code from Laravels base TestCase.php file. This file is used for testing within the Laravel framework (NOT using codeception).
To fix the 'Eloquent not found' error, add the following lines to project/tests/unit/_bootstrap.php
<?php
$app = require __DIR__.'/../../bootstrap/app.php';
$app->make('Illuminate\Contracts\Console\Kernel')->bootstrap();
Honestly I'm not sure why it works, but it does! I'll edit if I figure out why or someone comments.
The Eloquent class cannot be found when you are running your unit tests.
Try adding use Illuminate\Database\Eloquent\Model as Eloquent; to Role.php.
You can go to TestCase class and override method refreshApplication (add method to TestCase) with adding auth or some:
protected function refreshApplication()
{
$this->app = $this->createApplication();
$this->client = $this->createClient();
$this->app->setRequestForConsoleEnvironment();
$this->app->boot();
// authenticate your user here, when app is ready
$user = new User(array('username' => 'John', 'password' => 'test'));
$this->be($user);
}
I solved a similar problem with Laravel 4 and Codeception by adding the following lines to _bootstrap.php
$app = require __DIR__.'/../../bootstrap/start.php';
$app->boot();
Hope this helps a fellow googler!

Resources