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

Phpstan Mockery Laravel Package

phpstan/phpstan-mockery

PHPStan extension for Mockery: infers intersection types for mocks (Foo&MockInterface), understands shouldReceive/shouldHaveReceived/allows/expects, supports partial/alias/overload mocks, multiple interfaces, and proper constructor args for accurate static analysis.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package as a development dependency:

composer require --dev phpstan/phpstan-mockery

If you use phpstan/extension-installer, it’s auto-configured. Otherwise, include extension.neon manually in your PHPStan config. Your first use case: run PHPStan on a test file using Mockery — it will now understand mock types and method expectations correctly. For example, mockery::mock(Foo::class)->shouldReceive('bar') will no longer trigger “Method bar() does not exist” errors.

Implementation Patterns

  • Use Mockery::mock() and spy() as usual — the extension ensures PHPStan treats them as Foo&MockInterface, enabling autocompletion and strict type-checking on both the real contract and the mock API.
  • Annotate method parameters expecting mocks with Foo|\Mockery\MockInterface (e.g., in @param PHPDoc). By default, the extension converts this union to an intersection (Foo&MockInterface), which gives precise type inference without losing mock-specific methods.
  • Use expectation chaining like ->shouldReceive('foo')->andReturn('bar') — PHPStan recognizes these fluent methods as returning static, preserving type integrity across calls.
  • For partial mocks, write mockery::mock(Foo::class . '[bar]') or use shouldAllowMockingProtectedMethods() — both are typed and inferred correctly.
  • When using alias: or overload: prefixes in Mockery::mock(), PHPStan still infers the correct underlying type for safety checks.

Gotchas and Tips

  • Union-to-intersection conversion can be disabled: if you rely on strict union handling (e.g., passing mocks to generics expecting non-mockables), set mockery.convertUnionToIntersectionType: false in your config. Misconfigured, this may cause over-permissive type inference.
  • Mockery version compatibility matters: PHPStan Mockery 2.x requires PHP 8.0+, and newer Mockery versions (≥1.6.10). Older combos may cause stub mismatches — always match your PHPStan and PHP versions.
  • shouldReceive() et al. only on mocks: calling them on non-mock objects (e.g., real instances or incomplete mocks) won’t be caught at static analysis time unless you annotate parameter types explicitly — rely on strict type hints in constructor/type declarations to prevent misuse.
  • Partial mocks may lose precision: If you mock Foo[bar,baz], PHPStan may not distinguish between partial and full mocks in some scenarios — use strict @phpstan-assert MockInterface annotations for extra safety in test assertions.
  • Debug tip: Run PHPStan with --debug to see how types are interpreted — you’ll see intersection types like App\Entity\User&Mockery\MockInterface which helps verify correct behavior.
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport