如何在构造函数执行抽象方法(-s)时对抽象类进行单元测试?

时间:2013-12-24 16:06:05

标签: php unit-testing zend-framework2 phpunit abstract-class

我正在为这个PHPUnit类编写Zend Framework 2单元测试:

<?php
namespace MyNamespace\InputFilter;

use Zend\InputFilter\Input as ZendInput;
use Zend\InputFilter\Factory;
use Zend\InputFilter\InputInterface;
use MyNamespace\Exception\InvalidParameterException;

abstract class AbstractInput extends ZendInput
{
    final public function __construct()
    {
        // The constructor uses/executes the abstract method getInputSpecification().
        $this->init($this->getInputSpecification());
    }
    public function merge(InputInterface $input)
    {
        $mergedInput = parent::merge($input);
        $mergedInput->setFallbackValue($input->getFallbackValue());
        return $mergedInput;
    }
    public function isValid()
    {
        $this->injectNotEmptyValidator();
        $validator = $this->getValidatorChain();
        $value     = $this->getValue();
        $result    = $validator->isValid($value, $context);
        return $result;
    }
    protected function init($inputSpecification)
    {
        $factory = new Factory();
        $tempInput = $factory->createInput($inputSpecification);
        $this->merge($tempInput);
    }
    abstract protected function getInputSpecification();
    public function getFinalValue($param)
    {
        $finalValue = null;
        if (empty($param) || $this->getValue() === '') {
            if ($this->getFallbackValue() !== null) {
                $finalValue = $this->getFallbackValue();
            } else {
                throw new InvalidParameterException('The parameter ' . $this->name . ' must be set!');
            }
        } else {
            if ($this->isValid()) {
                $finalValue = $this->getValue();
            } else {
                throw new InvalidParameterException('The parameter ' . $this->name . ' is invalid!');
            }
        }
        return $finalValue;
    }
}

并遇到问题。这段代码

// ...
class AbstractInputTest extends TestCase
{
    // ...
    public function setUp()
    {
        $stub = $this->getMockForAbstractClass('\MyNamespace\InputFilter\AbstractInput');
        $stub
            ->expects($this->any())
            ->method('getInputSpecification')
            ->will($this->returnValue(array())
        );
        // ...
    }
    // ...
}

导致错误:

  

$ phpunit SgtrTest / InputFilter / AbstractInputTest.php Sebastian Bergmann的PHPUnit 3.7.21。

     

从/path/to/project/tests/phpunit.xml

读取配置      

E. ..

     

时间:1秒,记忆:7,00Mb

     

有1个错误:

     

1) SgtrTest \ InputFilter \ AbstractInputTest :: testMerge   Zend的\输入过滤\异常\ InvalidArgumentException:   Zend \ InputFilter \ Factory :: createInput需要一个数组或Traversable;   收到“NULL”

     

/path/to/project/vendor/ZF2/library/Zend/InputFilter/Factory.php:98   /path/to/project/vendor/SGTR/library/MyNamespace/InputFilter/AbstractInput.php:72   /path/to/project/vendor/SGTR/library/MyNamespace/InputFilter/AbstractInput.php:31   /path/to/project/tests/SgtrTest/InputFilter/AbstractInputTest.php:20

     

FAILURES!测试:4,断言:0,错误:1。

我不明白,为什么会抛出错误。如何以另一种方式解决这个问题?

1 个答案:

答案 0 :(得分:1)

在我的测试中,我创建了一个扩展抽象类的快速类,然后测试该类中的具体方法。

class TestAbstractInput extends AbstractInput
{
    ...
}

class AbstractInputTest extends TestCase
{
    // ...
    public function setUp()
    {
        $this->TestClassObject = new TestAbstractInput();
    }

    public function test_isValid()
    {
        $this->assertEquals(1, $this->TestClassObject->isValid);
    }
}

然后,您可以使用测试中创建的Abstract类的Mock对象,或者像您一样模拟Abstract类。