2

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?

IMSoP
  • 89,526
  • 13
  • 117
  • 169
Majesty
  • 2,097
  • 5
  • 24
  • 55

2 Answers2

1

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.

Mehdi
  • 683
  • 5
  • 16
0

Your above code should be working.

use Illuminate\Foundation\Testing\TestCase as BaseTestCase;

// add use from your ProviderStub class.

abstract class TestCase extends BaseTestCase
{
    public function setUp(): void
    {
        parent::setUp();
     
        $this->app->bind(ICompanyUserProvider::class, ProviderStub::class);
    }
}

Important

Confirm your test case extends TestCase from use Tests\TestCase; instead of use PHPUnit\Framework\TestCase;.

Feature tests will extends from Tests\TestCase; but unit tests is not.

Charlie
  • 287
  • 11