phpunit avoid constructor arguments for mock

后端 未结 7 1243
有刺的猬
有刺的猬 2021-01-30 08:24

What is the way to avoid phpunit having to call the constructor for a mock object? Otherwise I would need a mock object as constructor argument, another one for that etc. The ap

7条回答
  •  南笙
    南笙 (楼主)
    2021-01-30 08:48

    As an addendum, I wanted to attach expects() calls to my mocked object and then call the constructor. In PHPUnit 3.7.14, the object that is returned when you call disableOriginalConstructor() is literally an object.

    // 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)
    

    Unfortunately, in PHP 5.4 there is a new option which they aren't using:

    ReflectionClass::newInstanceWithoutConstructor

    Since this wasn't available, I had to manually reflect the class and then invoke the 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);
    

    Note, if functionCallFromConstruct is protected, you specifically have to use setMethods() so that the protected method is mocked. Example:

        $mock->setMethods(array('functionCallFromConstructor'));
    

    setMethods() must be called before the expect() call. Personally, I chain this after disableOriginalConstructor() but before getMock().

提交回复
热议问题