skip to Main Content

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 IlluminateFoundationTestingTestCase 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?

2

Answers


  1. Your above code should be working.

    use IlluminateFoundationTestingTestCase 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 TestsTestCase; instead of use PHPUnitFrameworkTestCase;.

    Feature tests will extends from TestsTestCase; but unit tests is not.

    Login or Signup to reply.
  2. Use app->instance to replace an instance in applicationContainer, here is an example:

    use IlluminateFoundationTestingTestCase 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
    IlluminateSupportFacadesFacade::swap in line 182, they used the same method for replacing facade accessor with a fake instance.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search