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

Test Double Bundle Laravel Package

docteurklein/test-double-bundle

Symfony bundle to simplify creating test doubles. Replace services automatically with stubs or fakes via DI container tags, improving test isolation and speed (e.g., Behat). Access original implementations with .real for infrastructure tests.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Symfony Ecosystem Alignment: The bundle is designed specifically for Symfony applications, leveraging its Dependency Injection Container (DIC) and tagging system. This makes it a natural fit for Symfony-based projects, particularly those using Behat or PHPUnit for testing.
  • Isolation-First Philosophy: The bundle aligns with modern testing best practices by promoting in-memory test doubles (stubs/fakes) over database-driven fixtures, reducing test pollution and improving isolation.
  • Modularity: The bundle operates at the service layer, allowing selective replacement of dependencies without modifying core business logic. This is ideal for unit/integration tests where controlled environments are critical.
  • Dual-Mode Testing: Supports both stubbed (Prophecy-based) and fake (custom implementation) approaches, offering flexibility for different testing scenarios.

Integration Feasibility

  • Low Friction for Symfony Projects: Requires minimal setup—just a Composer dependency and bundle registration in config/bundles.php. No major refactoring needed.
  • Prophecy Dependency: Relies on Prophecy for stubs, which is already a common testing library in PHP. If not present, it can be added as a dev dependency.
  • Behat Integration: Seamlessly integrates with Symfony2Extension, enabling service injection in Behat contexts. This is a high-value feature for BDD workflows.
  • Laravel Compatibility: Not natively supported (designed for Symfony). However, Laravel’s Service Container shares similarities with Symfony’s DIC, and the core concept (tag-based service replacement) could be adapted via a custom Laravel package or manual implementation (e.g., using Laravel’s bindWhen or replace methods).

Technical Risk

  • Deprecation Risk: Last release was 2016, raising concerns about:
    • PHP/Symfony Version Support: May not work with Symfony 5+ or PHP 8.x without modifications.
    • Maintenance: No active development; bugs or security issues may go unpatched.
    • Alternative Solutions: Modern tools like Symfony’s built-in test utilities (e.g., KernelTestCase, ServiceTestCase) or PestPHP may offer similar functionality with better support.
  • Laravel Porting Complexity:
    • Symfony’s tag-based service replacement has no direct Laravel equivalent. Would require:
      • Custom container extensions (e.g., ServiceProvider hooks).
      • Manual stub/fake registration logic.
      • Potential performance overhead from dynamic service binding.
  • Testing Overhead:
    • Prophecy learning curve for developers unfamiliar with mocking frameworks.
    • Real service access requires .real suffix (e.g., service.real), which could be confusing if not documented clearly.
  • Isolation Trade-offs:
    • Stubbed services do not persist across tests, which may force redundant setup in test suites.
    • Infrastructure tests (e.g., database-driven) must be explicitly separated, adding complexity to test classification.

Key Questions

  1. Symfony Version Compatibility:

    • Does the bundle work with Symfony 5.4+ or PHP 8.0+? If not, what modifications are needed?
    • Are there alternative modern bundles (e.g., Symfony Mock Component) that achieve the same goal with better support?
  2. Laravel Adaptation Feasibility:

    • What is the effort estimate to port this to Laravel? Would a custom package (e.g., laravel-test-doubles) be viable?
    • Are there Laravel-native alternatives (e.g., Mockery, PestPHP) that reduce the need for this bundle?
  3. Testing Strategy Impact:

    • How would this bundle change our current test structure? Would it require separating unit/integration/e2e tests more strictly?
    • What is the performance impact of dynamic service replacement vs. traditional mocking?
  4. Maintenance Plan:

    • If adopting this, how would we handle future deprecations? Would we fork the repo or migrate to a maintained alternative?
    • Are there community forks or similar maintained bundles we could use instead?
  5. Team Adoption:

    • How would this affect developer onboarding? Is the Prophecy-based approach familiar to the team?
    • Would this reduce or increase test flakiness in our current suite?

Integration Approach

Stack Fit

  • Symfony Projects: High fit—designed for Symfony’s DIC, tag system, and Behat integration. Ideal for teams already using:
    • Symfony Flex.
    • Behat + Mink for BDD.
    • Prophecy for mocking.
  • Laravel Projects: Low fit—requires significant adaptation. Alternatives like PestPHP or Mockery may be more straightforward.
  • Non-Symfony PHP: Not applicable—relies on Symfony-specific features.

Migration Path

For Symfony Projects

  1. Assessment Phase:
    • Audit current test suite for database-dependent tests and service dependencies that could benefit from stubbing.
    • Identify critical services (e.g., API clients, repositories) that are good candidates for doubling.
  2. Setup:
    • Install via Composer:
      composer require docteurklein/test-double-bundle --dev
      
    • Register the bundle only in test environments (e.g., config/bundles.php):
      TestDoubleBundle\TestDoubleBundle::class => ['env' => 'test'],
      
    • Add Prophecy if not already present:
      composer require --dev phpspec/prophecy
      
  3. Incremental Adoption:
    • Start with non-critical services (e.g., external API clients).
    • Tag services for stubbing/faking:
      # config/services_test.yaml
      services:
          App\Service\GithubClient:
              tags: ['test_double', { stub: 'GithubClient' }]
      
    • Update tests to use .prophecy services for assertions.
  4. Behat Integration:
    • Inject the container into Behat contexts:
      use Behat\MinkExtension\Context\MinkContext;
      use Symfony\Component\DependencyInjection\ContainerInterface;
      
      class FeatureContext extends MinkContext {
          public function __construct(ContainerInterface $container) {
              $this->container = $container;
          }
      }
      
    • Replace database fixtures with stubbed repositories.
  5. Infrastructure Tests:
    • Explicitly mark real-service tests (e.g., database tests) to run separately (e.g., via @group infrastructure).

For Laravel Projects

  1. Evaluation:
    • Assess whether the core goal (test isolation via doubles) can be achieved with native Laravel tools (e.g., partialMock, Mockery, or PestPHP).
    • If proceeding, consider building a custom Laravel package that mimics the bundle’s functionality.
  2. Custom Implementation Steps:
    • Extend Laravel’s Service Provider to:
      • Parse service tags (e.g., test_double).
      • Dynamically bind stub/fake services using bindWhen or replace.
    • Example:
      // app/Providers/TestDoubleServiceProvider.php
      public function register() {
          $this->app->when(GithubClient::class)
              ->needs(GithubClient::class)
              ->give(function ($app) {
                  return new FakeGithubClient();
              });
      }
      
    • Use Prophecy or Mockery for stubs.
  3. Behat/Laravel Integration:
    • Laravel’s PestPHP or PHPUnit can replace Behat for most use cases. If Behat is required:
      • Use Symfony’s BehatBundle alongside Laravel (complex).
      • Or, adapt the bundle’s container injection pattern to Laravel’s DI.

Compatibility

  • Symfony:
    • High compatibility with Symfony 2–4. Limited testing for Symfony 5+.
    • Conflicts: May clash with other bundles using similar DIC tags (e.g., test_double). Requires unique tag names.
  • Laravel:
    • No native compatibility. Custom implementation would need to handle:
      • Laravel’s service container differences (e.g., no tag-based replacement).
      • Autowiring vs. XML/YAML config.
  • PHP Version:
    • Likely PHP 5.6–7.1 only. May need polyfills for PHP 8.x (e.g., named arguments, union types).

Sequencing

  1. Phase 1: Proof of Concept
    • Implement stubbing for **1–
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity