2

I just began writing PHPUnit route tests on my laravel application and it's working fine via browser and Postman, not via PHPunit though.

Example: on this test

public function test_getAll(){
    $this->withoutExceptionHandling(); // If i comment this line I get the 404 and not the error shown below

    $response = $this->get('/api/users');
    $response->assertStatus(401);
}

I get:

PHPUnit 8.5.3 by Sebastian Bergmann and contributors.

.E                                                                  2 / 2 (100%)

Time: 1.89 seconds, Memory: 8.00 MB

There was 1 error:

1) Tests\Feature\Users\UserRoute_SuperAdminTest::test_getAll
Symfony\Component\HttpKernel\Exception\NotFoundHttpException: GET http://localhost/cms/api/users

E:\www\projects\cms-php\vendor\laravel\framework\src\Illuminate\Foundation\Testing\Concerns\InteractsWithExceptionHandling.php:126
E:\www\projects\cms-php\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php:415
E:\www\projects\cms-php\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php:113
E:\www\projects\cms-php\vendor\laravel\framework\src\Illuminate\Foundation\Testing\Concerns\MakesHttpRequests.php:468
E:\www\projects\cms-php\vendor\laravel\framework\src\Illuminate\Foundation\Testing\Concerns\MakesHttpRequests.php:258
E:\www\projects\cms-php\tests\Feature\Users\UsersRoute-SuperAdmin_Test.php:45

The weird thing is: if i change the URL to:

$response = $this->get('http://anythingatallinhere/api/users');

I get the 401 response that I should.

More context info to solve the problem.

My env APP_URL is APP_URL=http://localhost/cms and I am registering routes dynamically this way: I have a CoreServiceProvider with a boot procedure like this:

public function boot()
    {
       [...]
        $moduleController = app()->make(ModuleController::class);
        $moduleController->registerCoreRoutes();
       [...]
    }

on ModuleController:

function registerCoreRoutes(){
        foreach($this->allValidated as $moduleAlias => $registeredModule){
            $modName = ucfirst(str_replace('core/', '', strtolower($moduleAlias)));
            $namespace = 'App\Api\Core' . '\\' . $modName . '\Controllers';

            try {
                foreach ($registeredModule['routerFiles'] as $key => $routerInfo){
                    $routePath = app_path('Api/Core/' . $modName . '/Routes/' . $routerInfo['fileName'] . '.php');
                    $prefix = 'api/' . $routerInfo['path'];

                    $this->pathToModule[$routerInfo['path']] = $moduleAlias;

                    Route::prefix($prefix)
                        ->namespace($namespace)
                        ->group($routePath);
                }
                $this->allRegistered[$moduleAlias] = $registeredModule;
            } catch (\Throwable $th) {
                var_dump('Core module route registration failed');
                $this->allRegistered = [];
                throw $th;
            }
        }
    }

If I use php artisan route:list they are all there properly registered as well.

6
  • Try this $response = $this->get('api/users'); Commented Jul 21, 2020 at 23:21
  • Already tried all URL combinations that came in my mind, this included. I get the same thing Commented Jul 21, 2020 at 23:27
  • what are the full results for the relevant row in routes:list ? What happens if you resolve the route from the name and use that in the test, e.g. dump(route('api.users')); $this->get(route('api.users')); Commented Jul 21, 2020 at 23:34
  • @JamesClarkDeveloper it's too big to post as an answer so I'll post the first 2: | | GET|HEAD | api/users | users.list | App\Api\Core\User\Controllers\UserController@getAll | authjwt,getUserResource,can:read | | | PUT | api/users/editbasic/{id} | users.editBasic | App\Api\Core\User\Controllers\UserController@editBasicInfo | authjwt,getUserResource,can:update | Commented Jul 21, 2020 at 23:55
  • @JamesClarkDeveloper I did what you mentioned right after and still is returning the same error: dump(route('users.list')); $response = $this->get(route('users.list')); . PHPUnit 8.5.3 by Sebastian Bergmann and contributors. .E 2 / 2 (100%)"http://localhost/cms/api/users" Time: 2.2 seconds, Memory: 8.00 MB There was 1 error: 1) Tests\Feature\Users\UserRoute_SuperAdminTest::test_getAll Symfony\Component\HttpKernel\Exception\NotFoundHttpException: GET http://localhost/cms/api/users Commented Jul 22, 2020 at 0:00

2 Answers 2

1

I had a similar problem recently but it worked after running these:

php artisan config:clear
php artisan config:cache

Especially if you changed the just changed the APP_URL in your .env file.

You could also try setting processIsolation to true in your phpunit.xml file:

<phpunit backupGlobals="false"
 backupStaticAttributes="false"
 bootstrap="bootstrap/autoload.php"
 colors="true"
 convertErrorsToExceptions="true"
 convertNoticesToExceptions="true"
 convertWarningsToExceptions="true"
 processIsolation="true"
 stopOnFailure="false">

EDIT: If none of the above works, you could also create another .env.testing and set your APP_URL to http://localhost. PHPUnit will use variables from that file. This works regardless of the actual URL of your application

Sign up to request clarification or add additional context in comments.

4 Comments

Hey, @Clement Sam. Thanks for the answer. Already tried it. Tried those and php artisan route:clear and composer dump-autoload as well
I have edited my answer to include an alternative solution I normally work with
You could also create another .env.testing and set your APP_URL to http://localhost. PHPUnit will use variables from that file. This works regardless of the actual URL of your application
I already had the processIsolation="true" as I looked for countless solutions on stack overflow. Also I already had a .env.testing file with APP_URL set to http://localhost/cms. Changing it to http://localhost did the trick though. Now it's working properly. Since the /cms is part of the url, do you have any idea why it only works without it?
0

The easiest way would be to set APP_URL to http://localhost in the phpunit.xml file by adding this line:

<server name="APP_URL" value="http://localhost"/>

This method is best if you want to the variables in .env to still be available during testing. Creating your own .env.testing file will override all .env variables.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.