Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Symfony Mocker Container Laravel Package

polishsymfonycommunity/symfony-mocker-container

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require polishsymfonycommunity/symfony-mocker-container
    

    Add the package to your composer.json under require (as shown in the README).

  2. Configure Kernel: Override getContainerBaseClass() in AppKernel.php (or Kernel.php in Symfony 4+):

    protected function getContainerBaseClass()
    {
        if ('test' === $this->getEnvironment()) {
            return \PSS\SymfonyMockerContainer\DependencyInjection\MockerContainer::class;
        }
        return parent::getContainerBaseClass();
    }
    

    Clear cache:

    php bin/console cache:clear
    
  3. First Use Case: In a functional test (or Behat scenario), mock a service:

    $mock = $this->getMockBuilder('App\Service\MyService')
        ->disableOriginalConstructor()
        ->getMock();
    
    $this->container->set('app.my_service', $mock);
    

Implementation Patterns

Workflows

  1. Functional Tests:

    • Use MockerContainer to replace real services with mocks/stubs.
    • Example: Mocking a database service to return canned responses:
      $mockDb = $this->getMockBuilder('Doctrine\DBAL\Connection')
          ->disableOriginalConstructor()
          ->getMock();
      
      $mockDb->method('fetchAll')
          ->willReturn([['id' => 1, 'name' => 'Test']]);
      
      $this->container->set('database_connection', $mockDb);
      
  2. Behat Integration:

    • Combine with Symfony2MockerExtension for scenario-level mocking.
    • Example in a Behat context:
      use Behat\MinkExtension\Context\MinkContext;
      use PSS\SymfonyMockerExtension\Context\MockerContext;
      
      class FeatureContext extends MinkContext implements MockerContext {
          public function mockService($serviceId, $mockClass) {
              $mock = $this->getMockBuilder($mockClass)
                  ->disableOriginalConstructor()
                  ->getMock();
              $this->container->set($serviceId, $mock);
          }
      }
      
  3. Partial Mocking:

    • Mock only specific methods while keeping others real:
      $partialMock = $this->getMockBuilder('App\Service\Logger')
          ->setMethods(['log'])
          ->getMock();
      
      $partialMock->expects($this->once())
          ->method('log')
          ->with('Test message');
      
      $this->container->set('app.logger', $partialMock);
      

Integration Tips

  • Avoid in Unit Tests: This package is functional-test-only. Use PHPUnit's native mocking for unit tests.
  • BrowserKit Limitation: Only works with BrowserKitDriver (Symfony functional tests/Behat). HTTP-based drivers (e.g., Goutte) cannot use this.
  • Service Aliases: Mock aliases by resolving the target service first:
    $realService = $this->container->get('app.real_service');
    $mock = $this->getMockBuilder(get_class($realService))->getMock();
    $this->container->set('app.alias', $mock);
    

Gotchas and Tips

Pitfalls

  1. Cache Dependency:

    • Forgetting to clear the cache after changing AppKernel.php will cause the mocker container to not activate.
    • Always run:
      php bin/console cache:clear
      
  2. Environment Mismatch:

    • The mocker only activates in the test environment. Running tests in dev or prod will ignore the override.
  3. Non-Test Drivers:

    • Attempting to mock services with Goutte, Selenium2Driver, or other HTTP-based drivers will fail silently. The mocker only works with BrowserKitDriver.
  4. Lazy Services:

    • Services defined as lazy (lazy: true in YAML/XML) may not be mockable directly. Resolve them first:
      $this->container->get('app.lazy_service'); // Force initialization
      $mock = $this->getMockBuilder(get_class($service))->getMock();
      $this->container->set('app.lazy_service', $mock);
      
  5. Constructor Injection:

    • If a service has constructor arguments, mocking may fail unless you:
      • Use ->disableOriginalConstructor() or
      • Manually set up the mock to accept arguments.

Debugging

  • Verify Mock Activation: Check if the container is using the mocker by inspecting its class:
    $this->assertInstanceOf(
        \PSS\SymfonyMockerContainer\DependencyInjection\MockerContainer::class,
        $this->container
    );
    
  • Service Not Found: If $this->container->set() fails, the service ID might be incorrect. Verify with:
    $this->container->has('app.my_service'); // Returns bool
    
  • Mock Not Triggered: Ensure expectations are set correctly. Use ->shouldReceive() for older PHPUnit versions:
    $mock->shouldReceive('methodName')
         ->once()
         ->andReturn('mocked value');
    

Extension Points

  1. Custom Mock Factories: Extend the mocker to support custom mock creation:

    $this->container->set('app.custom_service', $this->createCustomMock());
    

    Example factory method:

    protected function createCustomMock() {
        return $this->getMockBuilder('App\Service\CustomService')
            ->setMethods(['customMethod'])
            ->getMock();
    }
    
  2. Reset Mocks Between Tests: Use PHPUnit's afterEach() to reset the container:

    public function tearDown(): void {
        $this->container = static::createClient()->getContainer();
    }
    
  3. Mocking Private Methods: Enable private method mocking (PHPUnit 5.3+):

    $mock = $this->getMockBuilder('App\Service\PrivateService')
        ->setMethods(['privateMethod'])
        ->getMock();
    $mock->expects($this->any())
         ->method('privateMethod')
         ->will($this->returnValue('mocked'));
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui