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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| // 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:
1
2
3
4
| // 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:
1
2
3
4
5
6
7
8
9
10
11
| 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:
1
2
3
4
5
6
7
8
9
10
11
12
13
| // 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'));
}
}
|
1
2
3
4
5
6
7
8
9
10
11
| 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.