Here is an example of how I declared my configuration for MyService
public function register(): void
{
$this->app->when(MyService::class)
->needs(IUser::class)
->give(fn (Application $app) => $app->make(ICompanyUserProvider::class)->getCompanyUser());
}
So I want to replace ICompanyUserProvider
implementation for testing purposes.
I have already seen a solution like this
$this->app->bind(
ICompanyUserProvider::class,
$this->app->runningUnitTests() ? ProviderStub::class : Provider::class
);
it works, but I find it inappropriate, I don't think it's a good practice to mix enviorenments in a single configuration.
Here is what else I tried so far:
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
abstract class TestCase extends BaseTestCase
{
public function setUp(): void
{
parent::setUp();
$this->app->bind(ICompanyUserProvider::class, ProviderStub::class);
}
}
but it does not work (provider not being replaced with a stub one).
Any ideas, please?
Use app->instance to replace an instance in applicationContainer, here is an example:
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
abstract class TestCase extends BaseTestCase
{
public function setUp(): void
{
parent::setUp();
$this->app->instance(ICompanyUserProvider::class, new ProviderStub());
}
}
If you look at the swap method from Facade class
\Illuminate\Support\Facades\Facade::swap
in line 182, they used the same method for replacing facade accessor with a fake instance.