Skip to content

Conversation

@kirkbushell
Copy link
Contributor

@kirkbushell kirkbushell commented Nov 16, 2025

As per the title, this isn't a solution to #1447 but instead illustrates the bug with a new test case.

We use the static return type for interfaces, as self can result in child classes not being able to work with said interface.

In short, if you have an interface method signature which has a static return type, mockery fails:

ParseError: syntax error, unexpected token "static", expecting identifier

The test case added shows this aspect failing. I've tried solving this but honestly, I am struggling to follow the mockery code, so any guidance would be appreciated and I'll update this PR to solve the problem appropriately.

Note that this can still be done with a hacky utility method we wrote as a wrapper to help us still use demeter chain expectations on interfaces:

protected function demeter(MockInterface $mock, string $chain): HigherOrderMessage|Expectation|ExpectationInterface
{
    $expectations = explode('->', $chain);
    $final = array_pop($expectations);

    $mock->shouldReceive(Arr::mapWithKeys($expectations, fn($expectation) => [$expectation => $mock]));

    return $mock->shouldReceive($final);
}

And it can also be done using array expectations:

$mock->shouldReceive(['do' => $mock, 'thing' => $mock])->andReturn(...);

So it seems to me that something funky is going on specifically with interfaces deeper down in the mockery code. Ideally, we want to be able to support demeter chain mocks on interface methods with static return types.

@kirkbushell kirkbushell changed the title Test to showcase problem with mocking interfcaes with static return types Test to showcase problem with mocking interfaces with static return types Nov 16, 2025
Changed the PHP requirement from '>=7.3|>=8.0' back to '>=7.3'.

Signed-off-by: Nathanael Esayeas <[email protected]>
Simplifies and clarifies the logic for creating and retrieving Demeter mocks, improving type annotations and removing the private noMoreElementsInChain helper.

Signed-off-by: Nathanael Esayeas <[email protected]>
Moved and updated the test for Demeter chains on interface subjects to require PHP >=8.0 and assert instance type instead of null. Removed the old version of the test.

Signed-off-by: Nathanael Esayeas <[email protected]>
Signed-off-by: Nathanael Esayeas <[email protected]>
@ghostwriter ghostwriter changed the base branch from 1.6.x to 1447-demeter-chain-mocking-an-interface-method-with-a-static-return-type January 10, 2026 21:51
@codecov
Copy link

codecov bot commented Jan 10, 2026

Codecov Report

❌ Patch coverage is 92.10526% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.30%. Comparing base (98e8fda) to head (50c34ad).
⚠️ Report is 1 commits behind head on 1.6.x.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
library/Mockery.php 92.10% 3 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##              1.6.x    #1474      +/-   ##
============================================
- Coverage     78.41%   78.30%   -0.11%     
+ Complexity     1042     1040       -2     
============================================
  Files            76       76              
  Lines          2622     2623       +1     
============================================
- Hits           2056     2054       -2     
- Misses          566      569       +3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@ghostwriter ghostwriter changed the base branch from 1447-demeter-chain-mocking-an-interface-method-with-a-static-return-type to 1.6.x January 10, 2026 21:54
@ghostwriter ghostwriter self-assigned this Jan 10, 2026
@ghostwriter ghostwriter added Patch Backwards compatible bug fixes and improvements Fixed for bug fixes or error corrections labels Jan 10, 2026
@ghostwriter ghostwriter added this to the 1.6.13 milestone Jan 10, 2026
@ghostwriter ghostwriter changed the title Test to showcase problem with mocking interfaces with static return types Mock interface methods with static return type Jan 10, 2026
@ghostwriter
Copy link
Member

Hey @kirkbushell,

Thank you for your contribution.

I appreciate the time you invested in preparing this pull request.

I was able to address the issue with a few additional commits.


Syntax:

$mock->shouldReceive('do->thing'); or $mock->shouldReceive('do->thing')->andReturnSelf();

@ghostwriter ghostwriter changed the title Mock interface methods with static return type Mock demeter chains and fluent interface methods with static return type Jan 10, 2026
@ghostwriter ghostwriter merged commit dd54ada into mockery:1.6.x Jan 10, 2026
24 of 25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Fixed for bug fixes or error corrections Patch Backwards compatible bug fixes and improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Mocking an interface method with a static return value as part of a demeter chain mock results in a fatal error

2 participants