You can use getMockBuilder
instead of just getMock
:
$mock = $this->getMockBuilder('class_name')
->disableOriginalConstructor()
->getMock();
See the section on "Test Doubles" in PHPUnit's documentation for details.
Although you can do this, it's much better to not need to. You can refactor your code so instead of a concrete class (with a constructor) needing to be injected, you only depend upon an interface. This means you can mock or stub the interface without having to tell PHPUnit to modify the constructor behaviour.
Here you go:
// Get a Mock Soap Client object to work with.
$classToMock = 'SoapClient';
$methodsToMock = array('__getFunctions');
$mockConstructorParams = array('fake wsdl url', array());
$mockClassName = 'MyMockSoapClient';
$callMockConstructor = false;
$mockSoapClient = $this->getMock($classToMock,
$methodsToMock,
$mockConstructorParams,
$mockClassName,
$callMockConstructor);
This question is a little old, but for new visitors, you can do it using the createMock
method (previously called createTestDouble
and introduced in v5.4.0).
$mock = $this->createMock($className);
As you can see in the code below extracted from the PHPUnit\Framework\TestCase
class (in phpunit/src/framework/TestCase.php
), it will basically create a mock object without calling the original constructor.
/** PHPUnit\Framework\TestCase::createMock method */
protected function createMock(string $originalClassName): MockObject
{
return $this->getMockBuilder($originalClassName)
->disableOriginalConstructor()
->disableOriginalClone()
->disableArgumentCloning()
->disallowMockingUnknownTypes()
->getMock();
}
As an addendum, I wanted to attach expects()
calls to my mocked object and then call the constructor. In PHPUnit 3.7.14, the object that is returned when you call disableOriginalConstructor()
is literally an object.
// Use a trick to create a new object of a class
// without invoking its constructor.
$object = unserialize(
sprintf('O:%d:"%s":0:{}', strlen($className), $className)
Unfortunately, in PHP 5.4 there is a new option which they aren't using:
ReflectionClass::newInstanceWithoutConstructor
Since this wasn't available, I had to manually reflect the class and then invoke the constructor.
$mock = $this->getMockBuilder('class_name')
->disableOriginalConstructor()
->getMock();
$mock->expect($this->once())
->method('functionCallFromConstructor')
->with($this->equalTo('someValue'));
$reflectedClass = new ReflectionClass('class_name');
$constructor = $reflectedClass->getConstructor();
$constructor->invoke($mock);
Note, if functionCallFromConstruct
is protected
, you specifically have to use setMethods()
so that the protected method is mocked. Example:
$mock->setMethods(array('functionCallFromConstructor'));
setMethods()
must be called before the expect()
call. Personally, I chain this after disableOriginalConstructor()
but before getMock()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With