'How do I prevent phpunit from overriding method type-hints

I have a wrapper that gives me a more convenient API to create mocks. You can ignore the implementation details. Just note the fact that:

  • it's a trait used on my test classes
  • the method used to obtain the mock is type-hinted
trait MockFacilitator {

        protected function positiveStub (string $target, array $overrides, array $constructorArguments = []):MockBuilder {

            $builder = $this->getBuilder($target, $constructorArguments, $overrides);

            $this->stubSingle($overrides, $builder);

            return $builder;
        }

    private function stubSingle (array $overrides, MockBuilder $builder):void {

            foreach ($overrides as $method => $newValue)

                $builder->expects($this->any())

                ->method($method)->will($this->returnValue($newValue));
        }

    private function getBuilder (string $target, array $constructorArguments, array $methodsToRetain):MockBuilder {

            $builder = $this->getMockBuilder($target);

            if (!empty($constructorArguments))

                $builder->setConstructorArgs($constructorArguments);

            if (!empty($methodsToRetain))

                $builder->setMethods(array_keys($methodsToRetain));

            return $builder->getMock();
        }

Used in my tests like so


$handler = $this->positiveStub(LoginRequestHandler::class, ["isValidRequest" => true]);

Now, the generated stub not only creates the new class that I want (LoginRequestHandler) , but creates new classes for the method return types as well(MockBuilder) ! As is explained on this thread https://fullstackuser.com/code-snippets/php-7-interfaces-return-type-hinting-and-self, such code will not compile.

Is it that phpunit dislikes type hinting method return types? I have seen on other threads that arguments with reference types will equally be overwritten; although in their case, the type was removed altogether, citing inability of phpunit to load those types as the reason. In my case, it probably mocks those return types as well

Is there a way to restrict type generation to only what goes into the mock builder? I prefer to leave out everything else as is in my original class



Solution 1:[1]

MockBuilder::disableAutoReturnValueGeneration() can be used to disable the automatic return value generation. The requires using the Mock Builder API instead of createStub(), createMock(), etc., of course.

Of course, automatic return value generation is not triggered, even when it is enabled, which is the default, when you explicitly configure return values for your stubs.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Sebastian Bergmann