¿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 $callOriginalConstructor
establece 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
functionCallFromConstruct
es 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
createMock
método (previamente llamadocreateTestDouble
e 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\TestCase
clase (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