Kuba T
Kuba T

Reputation: 3083

PHPUnit: mock non-existing classes

Is it possible to create a mock of non-existing class in PHPUnit?
Let's assume I have some class that creates instance of another class, for example:

class TaskRunner
{
    public function runTasks()
    {
        // Run through some loop to get tasks and store each in $taskName
        // Get task instance by given task name 
        $task = $this->getTaskInstance($taskName);
        if ($task instanceof AbstractTask) {
            $task->run();
        }
    }

    protected function getTaskInstance($taskName)
    {
        // Just an example
        return new $taskName();
    }
}

I would like to run unit test for runTasks method to check if created task instace extends some abstract class.
Is there any possibility to NOT to create sample class in a filesystem to check the inheritance constraint?
Thanks for all!

Upvotes: 29

Views: 10851

Answers (2)

Andrei Cristian
Andrei Cristian

Reputation: 93

The accepted answer is perfect, except that since PHPUnit 9 there is an issue, if you need to mock a class that is required to be of a certain instance. In that case \stdclass::class cannot be used.

And using

$this->getMockBuilder('UnexistentClass')->addMethods(['foo'])->getMock();

will result in Class UnexistentClass does not exist, because addMethod checks the given methods against the given class methods.

In case anybody else is having the same issue, luckly setMethods still works, so this still works in PHPUnit 9

$this->getMockBuilder('UnexistentClass')->setMethods(['foo'])->getMock();

Note though that setMethods will be removed in PHPUnit 10

Hopefully at that time there will be a fix for this issue. Like for example checking if allowMockingUnknownTypes is set to true. If that check is implemented this will then work too:

$this->getMockBuilder('UnexistentClass')->allowMockingUnknownTypes()
->addMethods(['foo'])->getMock();

Upvotes: 6

Sebastian Bergmann
Sebastian Bergmann

Reputation: 8306

Yes, it is possible to stub/mock classes that do not exist with PHPUnit. Simply do

 $this->getMockBuilder('NameOfClass')->setMethods(array('foo'))->getMock();

to create an object of non-existant class NameOfClass that provides one method, foo(), that can be configured using the API as usual.

Since PHPUnit 9, you shall replace :

  • 'NameOfClass' by \stdClass::class
  • setMethods by addMethods
$this->getMockBuilder(\stdclass::class)->addMethods(array('foo'))->getMock();

Upvotes: 50

Related Questions