Originally published at recca0120.github.io
When a third-party class requires constructor parameters, Laravel's container can't auto-resolve it. Directly type-hinting it for injection will throw an error.
Reproducing the Problem
Suppose there's a third-party FakeApi whose constructor requires a $token:
// app/FakeApi.php
namespace App;
class FakeApi
{
private string $token;
public function __construct(string $token)
{
$this->token = $token;
}
public function getToken(): string
{
return $this->token;
}
}
Type-hinting it directly in a route:
// routes/web.php
Route::get('/', static function (FakeApi $api) {
return $api->getToken();
});
The test will fail because the container doesn't know what value to pass for $token:
namespace Tests\Feature;
use Tests\TestCase;
class ExampleTest extends TestCase
{
public function test_inject_fake_api(): void
{
$this->get('/')->assertOk();
}
}
Register It in a ServiceProvider
In AppServiceProvider, use bind to tell the container how to create the class:
// app/Providers/AppServiceProvider.php
namespace App\Providers;
use App\FakeApi;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bind(FakeApi::class, fn() => new FakeApi('foo'));
}
}
namespace Tests\Feature;
use Tests\TestCase;
class ExampleTest extends TestCase
{
public function test_inject_fake_api(): void
{
$this->get('/')->assertOk()->assertSee('foo');
}
}
This also removes the dependency on Laravel-specific wrapper packages, which means one fewer thing to worry about during version upgrades.
Top comments (0)