W jaki sposób można uniknąć konieczności wywoływania konstruktora przez phpunit w celu uzyskania pozorowanego obiektu? W przeciwnym razie potrzebowałbym obiektu pozorowanego jako argumentu konstruktora, innego do tego itp. Interfejs API wygląda następująco:
getMock($className, $methods = array(), array $arguments = array(),
$mockClassName = '', $callOriginalConstructor = TRUE,
$callOriginalClone = TRUE, $callAutoload = TRUE)
Nie sprawiam, że to działa. Nadal narzeka na argument konstruktora, nawet przy $callOriginalConstructor
ustawieniu na false.
Mam tylko jeden obiekt w konstruktorze i jest to iniekcja zależności. Więc nie sądzę, żebym miał tam problem projektowy.
źródło
Proszę bardzo:
// 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);
źródło
Jako dodatek chciałem dołączyć
expects()
wywołania do mockowanego obiektu, a następnie wywołać konstruktora. W PHPUnit 3.7.14 obiekt, który jest zwracany podczas wywołania,disableOriginalConstructor()
jest dosłownie obiektem.// 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)
Niestety, w PHP 5.4 jest nowa opcja, której nie używają:
ReflectionClass :: newInstanceWithoutConstructor
Ponieważ nie było to dostępne, musiałem ręcznie odzwierciedlić klasę, a następnie wywołać konstruktora.
$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);
Zauważ, że jeśli
functionCallFromConstruct
takprotected
, musisz go specjalnie użyć,setMethods()
aby metoda chroniona była kpiona. Przykład:$mock->setMethods(array('functionCallFromConstructor'));
setMethods()
należy zadzwonić przedexpect()
wezwaniem. Osobiście łączę to po,disableOriginalConstructor()
ale wcześniejgetMock()
.źródło
Być może musisz utworzyć kod pośredniczący, który zostanie przekazany jako argument konstruktora. Następnie możesz przerwać ten łańcuch pozorowanych obiektów.
źródło
Alternatywnie możesz dodać parametr do getMock, aby zapobiec wywołaniu domyślnego konstruktora.
$mock = $this->getMock(class_name, methods = array(), args = array(), mockClassName = '', callOriginalConstructor = FALSE);
Mimo to myślę, że odpowiedź dave1010 wygląda ładniej, to tylko ze względu na kompletność.
źródło
To pytanie jest trochę stare, ale dla nowych użytkowników możesz to zrobić za pomocą
createMock
metody (poprzednio wywołanejcreateTestDouble
i wprowadzonej w wersji 5.4.0).$mock = $this->createMock($className);
Jak widać w poniższym kodzie wyodrębnionym z
PHPUnit\Framework\TestCase
klasy (inphpunit/src/framework/TestCase.php
), w zasadzie utworzy on obiekt pozorowany bez wywoływania oryginalnego konstruktora ./** PHPUnit\Framework\TestCase::createMock method */ protected function createMock(string $originalClassName): MockObject { return $this->getMockBuilder($originalClassName) ->disableOriginalConstructor() ->disableOriginalClone() ->disableArgumentCloning() ->disallowMockingUnknownTypes() ->getMock(); }
źródło
PHPUnit jest zaprojektowany do wywoływania konstruktora na mockowanych obiektach; aby temu zapobiec, należy:
źródło