Reputation: 3083
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
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
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