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

Phpspec2 Laravel Package

phpspec/phpspec2

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps to Begin

  1. Installation

    composer require --dev phpspec/phpspec
    

    Note: The package is now maintained at phpspec/phpspec, but the core usage remains identical.

  2. Initialize a Project

    vendor/bin/phpspec init
    

    This generates a basic phpspec.yml config file and example specs in spec/.

  3. First Use Case: Writing a Spec Create a spec file (e.g., spec/ExampleSpec.php) mirroring your class structure:

    namespace spec\App;
    
    use PhpSpec\ObjectBehavior;
    use App\Example;
    
    class ExampleSpec extends ObjectBehavior
    {
        public function it_is_initializable()
        {
            $this->shouldHaveType(Example::class);
        }
    }
    

    Run it with:

    vendor/bin/phpspec run
    
  4. Key Directories

    • spec/: Contains all spec files (auto-discovered).
    • phpspec.yml: Configuration (e.g., suites, extensions, formatter).

Implementation Patterns

Workflows

  1. BDD-First Development Write specs before implementation. Use it() methods to describe behavior:

    public function it_adds_two_numbers()
    {
        $this->add(2, 3)->shouldReturn(5);
    }
    

    Run specs incrementally:

    vendor/bin/phpspec run --stop-on-failure
    
  2. Mocking Dependencies Use addMock() or beConstructedWith() for external services:

    public function it_fetches_data_from_api()
    {
        $mockApi = $this->getMockBuilder('App\ApiClient')->getMock();
        $mockApi->method('fetch')->willReturn(['data']);
    
        $this->beConstructedWith($mockApi);
        $this->getData()->shouldReturn(['data']);
    }
    
  3. Data Providers Parameterize specs with with():

    public function it_returns_correct_discount($input, $expected)
    {
        $this->calculateDiscount($input)->shouldReturn($expected);
    }
    
    public function getMatchers()
    {
        return [
            'return_correct_discount' => function ($input, $expected) {
                return $this->calculateDiscount($input) === $expected;
            }
        ];
    }
    
  4. Suites and Tags Organize specs into suites in phpspec.yml:

    suites:
        unit:
            namespace: spec\App\Unit
            src_path: src/App
        integration:
            namespace: spec\App\Integration
            src_path: src/App
    

    Run a specific suite:

    vendor/bin/phpspec run --suite=unit
    
  5. Integration with Laravel

    • Service Providers: Mock Laravel’s container in specs:
      public function it_resolves_from_container()
      {
          $this->getContainer()->shouldHaveType('Illuminate\Container\Container');
      }
      
    • Database Testing: Use DatabaseMigrations extension (requires phpspec/prophecy-phpunit):
      extensions:
          PhpSpec\Extension\CodeCoverageExtension:
              format: [clover]
      

Integration Tips

  1. CI/CD Pipeline Add to composer.json scripts:

    "scripts": {
        "test": "phpunit",
        "spec": "phpspec run --format=pretty"
    }
    

    Run in CI:

    composer spec
    
  2. Code Coverage Generate reports with:

    vendor/bin/phpspec run --format=phpunit --stop-on-failure --code-coverage
    
  3. IDE Support

    • Use PHPStorm’s "Run Specs" shortcut (if configured).
    • Enable autotest for real-time feedback (e.g., with phpspec-watch).
  4. Legacy Code

    • Use PhpSpec\Exception\Example\SkippedException to skip unimplemented specs:
      public function it_should_be_implemented()
      {
          throw new SkippedException('Not implemented yet');
      }
      

Gotchas and Tips

Pitfalls

  1. Alpha State (Historical)

    • The package is now stable (moved to phpspec/phpspec), but old docs may reference phpspec2.
    • Avoid FIRST ALPHA warnings in output; ignore them post-migration.
  2. Mocking Static Methods

    • Problem: Static methods can’t be mocked directly.
    • Solution: Use partialMock() or refactor to dependency injection:
      $this->getWrappedObject()->staticMethod()->shouldReturn('mocked');
      
  3. Time-Based Specs

    • Problem: time() or DateTime specs may fail due to non-determinism.
    • Solution: Mock DateTime or use PhpSpec\Wrapper\DateTimeWrapper:
      $this->getWrappedObject()->getDate()->shouldBeLike(new \DateTime('2023-01-01'));
      
  4. Laravel’s Service Container

    • Problem: Mocking Laravel’s app() can be verbose.
    • Tip: Use PhpSpec\ServiceContainer\Container extension:
      extensions:
          PhpSpec\ServiceContainer\Container:
              container: '@'
      
  5. Performance with Large Suites

    • Problem: Slow runs with many specs.
    • Tip: Split into suites or use --filter:
      vendor/bin/phpspec run --filter="UserSpec"
      

Debugging

  1. Verbose Output Enable debug mode:

    vendor/bin/phpspec run -vvv
    
  2. Isolation Issues

    • Symptom: Specs pass alone but fail in suite.
    • Fix: Ensure no shared state (e.g., static vars). Use before()/after():
      public function before()
      {
          $this->resetStaticProperty('App\Example::$counter');
      }
      
  3. Prophecy Mismatches

    • Error: Prophecy\Exception\Double\MethodNotFoundException.
    • Cause: Method signature mismatch in mocks.
    • Debug: Use ->shouldReceive()->once() to enforce expectations.

Configuration Quirks

  1. Custom Formatters

    • Add to phpspec.yml:
      formatter:
          name: pretty
          # or
          name: json
          path: phpspec.json
      
  2. Excluding Files

    exclude:
        - spec/ExampleSpec.php
    
  3. Parallel Execution

    • Warning: Not officially supported; may cause race conditions.
    • Alternative: Use php-parallel-lint for static analysis.

Extension Points

  1. Custom Matchers Extend PhpSpec\Matcher\Matcher:

    namespace spec\App\Matcher;
    
    use PhpSpec\Matcher\Matcher;
    
    class BeEven extends Matcher
    {
        public function match($value)
        {
            return $value % 2 === 0;
        }
    }
    

    Register in phpspec.yml:

    extensions:
        App\Matcher\BeEven:
            namespace: spec\App\Matcher
    
  2. Hooks Implement PhpSpec\Event\EventListener for pre/post-spec hooks:

    public function beforeExample(ExampleEvent $event)
    {
        if ($event->getExample()->getDescription() === 'it_loads_data') {
            $event->skip('Skipping DB-heavy spec');
        }
    }
    
  3. Custom Loaders Override PhpSpec\Loader\LoaderInterface to load specs from non-standard paths (e.g., JSON).

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.
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
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment