Phpunit escape constructor arguments for mock

How can I avoid calling phpunit to invoke the constructor for the layout? Otherwise, I would need a mock object as an argument to the constructor, another for this, etc. Api is as follows:

getMock($className, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = TRUE, $callOriginalClone = TRUE, $callAutoload = TRUE) 

I do not work. It still complains about the constructor argument, even if $callOriginalConstructor set to false.

I have only one object in the constructor, and this is a dependency injection. So I don’t think I have a design problem.

+73
php unit-testing phpunit
Nov 10 '08 at 23:00
source share
6 answers

Instead of getMock you can use getMockBuilder :

 $mock = $this->getMockBuilder('class_name') ->disableOriginalConstructor() ->getMock(); 

See the Double Tests section of the PHPUnit documentation for more details.

Although you can do this, much better is not needed. You can reorganize your code, so instead of the specific class (with the constructor) that you need to enter, you will depend only on the interface. This means that you can mock or stub the interface without telling PHPUnit to change the constructor behavior.

+121
Jun 08 '11 at 10:11
source share
β€” -

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); 
+40
Mar 09 '09 at 22:38
source share

As an addition, 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 disableOriginalConstructor() called 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 parameter that they do not use:

ReflectionClass :: newInstanceWithoutConstructor

Since this was not available, I had to manually display the class and then call 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 that if functionCallFromConstruct is protected , you need to use setMethods() to make the protected method mock. Example:

  $mock->setMethods(array('functionCallFromConstructor')); 

setMethods() must be called before expect() called. Personally, I bind this through disableOriginalConstructor() , but before getMock() .

+3
Mar 08 '13 at 2:21
source share

You might need to create a stub to pass as a constructor argument. Then you can break this chain of mock objects.

+1
Dec 01 '08 at 22:30
source share

Alternatively, you can add the getMock parameter to prevent the default constructor from being called.

 $mock = $this->getMock(class_name, methods = array(), args = array(), mockClassName = '', callOriginalConstructor = FALSE); 

However, I think the dave1010 answer looks better, this is only for the sake of completeness.

+1
Jul 21 '14 at 7:37
source share

PHPUnit is designed to invoke the constructor on mocking objects; To prevent this, you need to:

  • Make a mock object dependent on the object you encounter, mock
  • Create a test class that extends the class you are trying to call, which does not call the parent constructor
0
Dec 08 '08 at 21:08
source share



All Articles