DEV Community

Cover image for Debugging Laravel Routes in Testing
Nasrul Hazim Bin Mohamad
Nasrul Hazim Bin Mohamad

Posted on

Debugging Laravel Routes in Testing

Laravel’s routing system is one of its core strengths, providing an elegant way to define and handle application routes. While php artisan route:list is a great tool for listing routes, it’s not always convenient when debugging in code or during automated testing.

To address this, let’s build a utility function, routes, that retrieves all registered routes in a structured format. This function is especially useful for testing or debugging complex route setups.


Support my mission to empower the developer community by sponsoring my work—your contributions help me build and share valuable tools, insights, and resources: Learn more here.


Why Use the routes Function?

When working on tests or debugging route configurations, you might need to:

  • Verify that specific routes exist.
  • Check route names, URIs, or methods programmatically.
  • Debug routes without relying on Artisan commands or running them outside the test environment.

The routes function provides a simple, reusable way to access and inspect routes in your application.


The routes Function

Here’s the implementation:

use Illuminate\Support\Facades\Route;

if (!function_exists('routes')) {
    /**
     * Retrieve all registered routes for debugging in a structured format.
     *
     * @param bool $dump Whether to dump the routes to the console.
     * @return \Illuminate\Support\Collection A collection of routes with details.
     */
    function routes(bool $dump = false)
    {
        $routes = collect(Route::getRoutes())->map(function ($route) {
            return [
                'uri' => $route->uri(),
                'name' => $route->getName(),
                'action' => $route->getActionName(),
                'methods' => $route->methods(),
            ];
        });

        if ($dump) {
            dump($routes); // Dumps routes to the console
        }

        return $routes;
    }
}
Enter fullscreen mode Exit fullscreen mode

How to Use the routes Function

  1. Debugging Routes in a Test:

    Use the function in a test to inspect all registered routes:

    it('retrieves all routes for debugging', function () {
        $all_routes = routes(true); // Dumps routes to the console
    
        $route_names = $all_routes->pluck('name')->all();
        expect($route_names)->toContain('home');
        expect($route_names)->toContain('dashboard');
    });
    
  2. Customising Route Output:

    Filter or transform the routes as needed:

    it('retrieves only POST routes', function () {
        $post_routes = routes()
            ->filter(fn($route) => in_array('POST', $route['methods']));
    
        expect($post_routes->count())->toBeGreaterThan(0);
    });
    
  3. Inspecting Routes in Development:

    Create a debugging route in your application to view all routes in JSON format:

    Route::get('/debug-routes', function () {
        return routes(); // Returns all routes as a JSON response
    });
    

Example Output

Calling routes(true) will display something like this:

[
    {
        "uri": "home",
        "name": "home",
        "action": "App\Http\Controllers\HomeController@index",
        "methods": ["GET", "HEAD"]
    },
    {
        "uri": "dashboard",
        "name": "dashboard",
        "action": "App\Http\Controllers\DashboardController@index",
        "methods": ["GET", "HEAD"]
    },
    ...
]
Enter fullscreen mode Exit fullscreen mode

This structured output makes it easier to inspect and debug your routes.


Benefits of routes

  • Convenient Debugging: Quickly view and debug routes without leaving the code.
  • Improved Test Coverage: Validate your routes programmatically during testing.
  • Reusable Utility: Easily integrate into any Laravel project for route inspection.

Conclusion

The routes function is a lightweight and flexible helper for inspecting Laravel routes in a programmatic way. Whether you're debugging in development or validating routes during testing, this function simplifies your workflow and eliminates guesswork.

What do you think of the routes function? Let me know how you use it in your projects, and don’t forget to share this post with others!


Support my mission to empower the developer community by sponsoring my work—your contributions help me build and share valuable tools, insights, and resources: Learn more here.


Photo by Codioful (Formerly Gradienta) on Unsplash

Top comments (3)

Collapse
 
xwero profile image
david duymelinck

I like the way you are thinking. But getting all the routes for every route test is wasteful in my opinion.

artisan route:list has a --json option. And you can filter the routes list with other options. So all you need to do is $json = shell_exec('php artisan route:list --json'/* and extra filters if needed*/). That returns a json object you can use as you please.

Collapse
 
nasrulhazim profile image
Nasrul Hazim Bin Mohamad

I would not prefer to use shell_exec actually, just rely on any internal PHP classes.

But your approach using the route:list, can be done in the helper:

$routes = collect(
    json_decode(Artisan::call('route:list --path=admin --json'))
);
Enter fullscreen mode Exit fullscreen mode

Where --path can be add as optional argument in the helper.

The Illuminate\Support\Facades\Route class actually in the route:list command if you drill down a bit more the route:list command.

Collapse
 
xwero profile image
david duymelinck

Artisan::call doesn't return the output. It returns the exit code.

The sentence; I would not prefer to use shell_exec actually, just rely on any internal PHP classes, puzzles me. Do you mean you prefer to use Laravel classes over php functions?