¿Cuál es la forma de evitar que phpunit tenga que llamar al constructor para un objeto simulado? De lo contrario, necesitaría un objeto simulado como argumento de constructor, otro para eso, etc. La api parece ser así:
getMock($className, $methods = array(), array $arguments = array(),
$mockClassName = '', $callOriginalConstructor = TRUE,
$callOriginalClone = TRUE, $callAutoload = TRUE)
No consigo que funcione. Todavía se queja del argumento del constructor, incluso si se $callOriginalConstructorestablece en falso.
Solo tengo un objeto en el constructor y es una inyección de dependencia. Entonces no creo que tenga un problema de diseño allí.
fuente

Aqui tienes:
// 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);fuente
Como apéndice, quería adjuntar
expects()llamadas a mi objeto simulado y luego llamar al constructor. En PHPUnit 3.7.14, el objeto que se devuelve cuando llamadisableOriginalConstructor()es literalmente un objeto.// 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)Desafortunadamente, en PHP 5.4 hay una nueva opción que no están usando:
ReflectionClass :: newInstanceWithoutConstructor
Como esto no estaba disponible, tuve que reflejar manualmente la clase y luego invocar el 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);Tenga en cuenta que, si
functionCallFromConstructes asíprotected, debe usarlo específicamentesetMethods()para que se burle del método protegido. Ejemplo:$mock->setMethods(array('functionCallFromConstructor'));setMethods()debe ser llamado antes de laexpect()llamada. Personalmente, encadeno esto despuésdisableOriginalConstructor()pero antesgetMock().fuente
Quizás necesite crear un código auxiliar para pasarlo como argumento del constructor. Entonces puedes romper esa cadena de objetos simulados.
fuente
Alternativamente, puede agregar un parámetro a getMock para evitar la llamada del constructor predeterminado.
$mock = $this->getMock(class_name, methods = array(), args = array(), mockClassName = '', callOriginalConstructor = FALSE);Aún así, creo que la respuesta de dave1010 se ve mejor, esto es solo para completar.
fuente
Esta pregunta es un poco vieja, pero para los nuevos visitantes, puede hacerlo usando el
createMockmétodo (previamente llamadocreateTestDoublee introducido en v5.4.0).$mock = $this->createMock($className);Como puede ver en el código a continuación extraído de la
PHPUnit\Framework\TestCaseclase (enphpunit/src/framework/TestCase.php), básicamente creará un objeto simulado sin llamar al constructor original ./** PHPUnit\Framework\TestCase::createMock method */ protected function createMock(string $originalClassName): MockObject { return $this->getMockBuilder($originalClassName) ->disableOriginalConstructor() ->disableOriginalClone() ->disableArgumentCloning() ->disallowMockingUnknownTypes() ->getMock(); }fuente
PHPUnit está diseñado para llamar al constructor en objetos simulados; para evitar esto, debe:
fuente