Search code examples
laravellaravel-routing

Testing Custom Route Model Binding


I'm trying to test a custom class that implements \Illuminate\Contracts\Routing\UrlRoutable and can't get the resolveRouteBinding method invoked.

<?php

namespace Tests\Unit;

use Illuminate\Support\Facades\Route;
use Tests\TestCase;

class BindingExampleClassTest extends TestCase
{
    function test_invoke_resolve_route_binding_method()
    {
        Route::get('/invoke-route-binding/{binding}', function (BindingExampleClass $binding) {
            dd($binding);
        });

        $this->get('/invoke-route-binding/1');
    }
}

class BindingExampleClass implements \Illuminate\Contracts\Routing\UrlRoutable
{
    public $id;

    public function resolveRouteBinding($value, $field = null)
    {
        $this->id = $value;
    }

    public function getRouteKey()
    {
        // TODO: Implement getRouteKey() method.
    }

    public function getRouteKeyName()
    {
        // TODO: Implement getRouteKeyName() method.
    }

    public function resolveChildRouteBinding($childType, $value, $field)
    {
        // TODO: Implement resolveChildRouteBinding() method.
    }
}

The dd response is BindingExampleClass with id still null.


Solution

  • Registering route inside a test function will not include any middleware. When working with route model binding in Laravel, \Illuminate\Routing\Middleware\SubstituteBindings::class middleware must be defined in the router instance.

    Route::get('/invoke-route-binding/{binding}', function (BindingExampleClass $binding) {
        dd($binding);
    })->middleware(\Illuminate\Routing\Middleware\SubstituteBindings::class);