Как избежать вызова phpunit конструктора для фиктивного объекта? В противном случае мне понадобится фиктивный объект в качестве аргумента конструктора, другой для этого и т. Д. Кажется, что api выглядит так:
getMock($className, $methods = array(), array $arguments = array(),
$mockClassName = '', $callOriginalConstructor = TRUE,
$callOriginalClone = TRUE, $callAutoload = TRUE)
Я не могу заставить его работать. Он по-прежнему жалуется на аргумент конструктора, даже если для него $callOriginalConstructor
установлено значение false.
У меня только один объект в конструкторе, и это инъекция зависимости. Так что я не думаю, что у меня здесь проблемы с дизайном.
источник
Ну вот:
// 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);
источник
В качестве дополнения я хотел прикрепить
expects()
вызовы к своему фиктивному объекту, а затем вызвать конструктор. В PHPUnit 3.7.14 объект, который возвращается при вызовеdisableOriginalConstructor()
, буквально является объектом.// 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)
К сожалению, в PHP 5.4 есть новая опция, которую они не используют:
ReflectionClass :: newInstanceWithoutConstructor
Поскольку это было недоступно, мне пришлось вручную отразить класс, а затем вызвать конструктор.
$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);
Обратите внимание: если
functionCallFromConstruct
это такprotected
, вы должны использовать специально дляsetMethods()
имитации защищенного метода. Пример:$mock->setMethods(array('functionCallFromConstructor'));
setMethods()
должен быть вызван доexpect()
звонка. Лично я связываю это после,disableOriginalConstructor()
но доgetMock()
.источник
Возможно, вам нужно создать заглушку для передачи в качестве аргумента конструктора. Затем вы можете разорвать эту цепочку фиктивных объектов.
источник
В качестве альтернативы вы можете добавить параметр в getMock, чтобы предотвратить вызов конструктора по умолчанию.
$mock = $this->getMock(class_name, methods = array(), args = array(), mockClassName = '', callOriginalConstructor = FALSE);
Тем не менее, я думаю, что ответ dave1010 выглядит лучше, это просто для полноты картины.
источник
Этот вопрос немного устарел, но для новых посетителей вы можете сделать это с помощью
createMock
метода (ранееcreateTestDouble
вызывавшегося и представленного в v5.4.0).$mock = $this->createMock($className);
Как вы можете видеть в приведенном ниже коде, извлеченном из
PHPUnit\Framework\TestCase
класса (inphpunit/src/framework/TestCase.php
), он в основном создает фиктивный объект без вызова исходного конструктора ./** PHPUnit\Framework\TestCase::createMock method */ protected function createMock(string $originalClassName): MockObject { return $this->getMockBuilder($originalClassName) ->disableOriginalConstructor() ->disableOriginalClone() ->disableArgumentCloning() ->disallowMockingUnknownTypes() ->getMock(); }
источник
PHPUnit предназначен для вызова конструктора имитируемых объектов; чтобы предотвратить это, вам следует:
источник