Qual é a maneira de evitar que o phpunit tenha que chamar o construtor de um objeto mock? Caso contrário, eu precisaria de um objeto fictício como argumento do construtor, outro para isso etc. A api parece ser assim:
getMock($className, $methods = array(), array $arguments = array(),
$mockClassName = '', $callOriginalConstructor = TRUE,
$callOriginalClone = TRUE, $callAutoload = TRUE)
Eu não consigo fazer funcionar. Ele ainda reclama do argumento do construtor, mesmo com $callOriginalConstructor
definido como falso.
Tenho apenas um objeto no construtor e é uma injeção de dependência. Então eu não acho que tenho um problema de design aí.
fonte
Aqui está:
// 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);
fonte
Como um adendo, eu queria anexar
expects()
chamadas ao meu objeto simulado e, em seguida, chamar o construtor. No PHPUnit 3.7.14, o objeto que é retornado quando você chamadisableOriginalConstructor()
é literalmente um 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)
Infelizmente, no PHP 5.4 há uma nova opção que eles não estão usando:
ReflectionClass :: newInstanceWithoutConstructor
Como isso não estava disponível, tive que refletir manualmente a classe e, em seguida, invocar o construtor.
$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);
Observe, se
functionCallFromConstruct
forprotected
, você precisa usar especificamente parasetMethods()
que o método protegido seja simulado. Exemplo:$mock->setMethods(array('functionCallFromConstructor'));
setMethods()
deve ser chamado antes daexpect()
chamada. Pessoalmente, eu encerro isso depois,disableOriginalConstructor()
mas antesgetMock()
.fonte
Talvez você precise criar um stub para passar como o argumento do construtor. Então você pode quebrar essa cadeia de objetos fictícios.
fonte
Como alternativa, você pode adicionar um parâmetro para getMock para evitar a chamada do construtor padrão.
$mock = $this->getMock(class_name, methods = array(), args = array(), mockClassName = '', callOriginalConstructor = FALSE);
Ainda assim, acho que a resposta de dave1010 parece melhor, isso é apenas por uma questão de completude.
fonte
Esta questão é um pouco antiga, mas para novos visitantes, você pode fazer isso usando o
createMock
método (anteriormente chamadocreateTestDouble
e introduzido na v5.4.0).$mock = $this->createMock($className);
Como você pode ver no código abaixo extraído da
PHPUnit\Framework\TestCase
classe (inphpunit/src/framework/TestCase.php
), ele basicamente criará um objeto simulado sem chamar o construtor original ./** PHPUnit\Framework\TestCase::createMock method */ protected function createMock(string $originalClassName): MockObject { return $this->getMockBuilder($originalClassName) ->disableOriginalConstructor() ->disableOriginalClone() ->disableArgumentCloning() ->disallowMockingUnknownTypes() ->getMock(); }
fonte
PHPUnit é projetado para chamar o construtor em objetos simulados; para evitar isso, você deve:
fonte