#250·prophecy

Spies and PHP7 return typehinting

Author: Sam-BurnsCreated Jan 28, 2016Updated Apr 2, 2024
Labelsbug

Spies don't work with PHP return typehinting.

Example in repo at https://github.com/Sam-Burns/prophecy-bug-demo for now; code cut-and-paste below for prosperity.

Reproducible step: Clone the repo, run Composer, and run PHPSpec. Expected result: Spec passes. Actual result:

✘ Fatal error happened while executing the following
    it calls something on its dependency
    Uncaught TypeError: Return value of Double\DependencyWithReturnTypehinting\P1::getAnInt() must be of the type integer, null returned in

The basic problem seems to be that spies don't return anything, so you can't make a spy of a class which uses return typehinting. Perhaps a solution might be to catch \Throwable, \Error or something when calling methods on spies, but I don't really know because I've never read the Prophecy codebase.

The code in the temporary repo demonstrating the bug is (was) as follows:

php
<?php
class SubjectUnderTest
{
    public function getAnIntFromThisThing(DependencyWithReturnTypehinting $dependencyWithReturnTypehinting)
    {
        $int = $dependencyWithReturnTypehinting->getAnInt();
    }
}
php
<?php
class DependencyWithReturnTypehinting
{
    public function getAnInt(): int
    {
        return 42;
    }
}
php
<?php
namespace spec;
use PhpSpec\ObjectBehavior;
class SubjectUnderTestSpec extends ObjectBehavior
{
    function it_calls_something_on_its_dependency(\DependencyWithReturnTypehinting $dependencyWithReturnTypehinting)
    {
        $this->getAnIntFromThisThing($dependencyWithReturnTypehinting);
        $dependencyWithReturnTypehinting->getAnInt()->shouldHaveBeenCalled();
    }
}