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

Functional Test Bundle Laravel Package

liip/functional-test-bundle

Symfony bundle providing base classes and helpers for functional tests, plus a DI-aware mock builder for unit tests. Includes tools for command testing, logged clients, query counting, examples, and parallel test runs.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require --dev liip/functional-test-bundle
    

    Add the bundle to config/bundles.php under test environment:

    Liip\FunctionalTestBundle\LiipFunctionalTestBundle::class => ['test' => true],
    
  2. Extend Base Class: Replace Symfony\Bundle\FrameworkBundle\Test\WebTestCase with:

    use Liip\FunctionalTestBundle\Test\WebTestCase;
    
    class MyTest extends WebTestCase
    
  3. First Test Case:

    public function testHomepage()
    {
        $client = $this->makeClient();
        $client->request('GET', '/');
        $this->assertStatusCode(200, $client);
    }
    

Key First Use Cases

  • Authenticated Requests: Use makeClient(['username' => 'test', 'password' => 'test']) or configure in config/packages/test/liip_functional_test.yaml.
  • Service Mocking: Mock services in unit tests with getServiceMockBuilder().
  • Query Counting: Track database queries with QueryCounter (see Query Counter docs).

Implementation Patterns

Core Workflows

1. Authenticated Testing

// Option 1: Config-based (config/packages/test/liip_functional_test.yaml)
liip_functional_test:
    authentication:
        username: test@example.com
        password: secret

// Option 2: Inline credentials
$client = $this->makeClient(['username' => 'test', 'password' => 'secret']);

// Option 3: Fixture-based login
$client = $this->makeClient();
$this->loginClient($client, $this->getReference('user'), 'main');

2. Service Mocking in Unit Tests

public function testMockedService()
{
    $mock = $this->getServiceMockBuilder(MyService::class)
        ->disableOriginalConstructor()
        ->getMock();

    $mock->method('doWork')->willReturn('mocked');

    $this->setServiceMock($this->getContainer(), MyService::class, $mock);

    $controller = new MyController($mock);
    $response = $controller->indexAction();
    $this->assertEquals('mocked', $response);
}

3. Command Testing

public function testCommand()
{
    $client = $this->makeClient();
    $output = $this->runCommand($client, 'app:command', ['--option' => 'value']);
    $this->assertStringContainsString('Expected output', $output);
}

4. Query Assertions

public function testQueryCount()
{
    $client = $this->makeClient();
    $counter = new QueryCounter($client->getContainer()->get('doctrine')->getConnection());
    $client->request('GET', '/');
    $this->assertEquals(3, $counter->getCount());
}

Integration Tips

  • Kernel Reboot: Use static::ensureKernelShutdown() before mocking services if they’re already loaded.
  • Parallel Tests: Configure config/packages/test/liip_functional_test.yaml:
    liip_functional_test:
        parallel:
            enabled: true
            workers: 4
    
  • HTTP Basic Auth: For faster tests, enable in config/packages/test/security.yaml:
    security:
        firewalls:
            main:
                http_basic: ~
    

Gotchas and Tips

Pitfalls

  1. Session Storage Errors:

    • Error: Missing session.storage.options#name.
    • Fix: Add to config/packages/test/framework.yaml:
      framework:
          session:
              name: MOCKSESSID
      
  2. Service Mocking Quirks:

    • Issue: Mocks not working if services are already instantiated.
    • Fix: Reboot the kernel (static::ensureKernelShutdown()) or set reuseKernel: true in runCommand().
  3. Fixture References:

    • Error: getReference() fails if fixtures aren’t loaded.
    • Fix: Load fixtures first:
      $fixtures = $this->loadFixtures([UserFixture::class])->getReferenceRepository();
      
  4. Parallel Tests:

    • Issue: Shared state between tests.
    • Fix: Use static::bootKernel() and static::ensureKernelShutdown() explicitly.

Debugging Tips

  • Query Logging: Enable with:
    $counter = new QueryCounter($connection, true); // Enable logging
    
  • Client Debug: Dump response:
    $this->dumpClient($client); // Shows headers, content, and status
    
  • Service Mock Verification:
    $this->assertServiceMockCalled(MyService::class, 'doWork');
    

Extension Points

  1. Custom Assertions: Extend WebTestCase to add domain-specific assertions:

    class CustomTestCase extends WebTestCase
    {
        protected function assertFlashMessageContains($message)
        {
            $this->assertStringContainsString($message, $this->getSession()->getFlashBag()->get('notice'));
        }
    }
    
  2. Query Counter Extensions: Subclass QueryCounter to track specific queries:

    class CustomQueryCounter extends QueryCounter
    {
        public function trackSelectsOnly()
        {
            $this->trackQueries('SELECT');
        }
    }
    
  3. Authentication Providers: Extend AuthenticationProvider for custom auth logic:

    class ApiTokenAuthProvider implements AuthenticationProviderInterface
    {
        public function authenticate(array $credentials)
        {
            // Custom logic
        }
    }
    

Configuration Quirks

  • Test Environment Isolation: Ensure config/packages/test/ overrides are not loaded in production. Use when@test in services.yaml:
    services:
        _defaults:
            autowire: true
            autoconfigure: true
            public: true # Critical for mocking!
    
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