I’m writing PHPUnit
unit tests for this Zend Framework 2
class:
<?php
namespace MyNamespaceInputFilter;
use ZendInputFilterInput as ZendInput;
use ZendInputFilterFactory;
use ZendInputFilterInputInterface;
use MyNamespaceExceptionInvalidParameterException;
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;
}
}
and get a problem with this. This code
// ...
class AbstractInputTest extends TestCase
{
// ...
public function setUp()
{
$stub = $this->getMockForAbstractClass('MyNamespaceInputFilterAbstractInput');
$stub
->expects($this->any())
->method('getInputSpecification')
->will($this->returnValue(array())
);
// ...
}
// ...
}
causes an error:
$ phpunit SgtrTest/InputFilter/AbstractInputTest.php PHPUnit 3.7.21 by Sebastian Bergmann.
Configuration read from /path/to/project/tests/phpunit.xml
E…
Time: 1 second, Memory: 7,00Mb
There was 1 error:
1) SgtrTestInputFilterAbstractInputTest::testMerge
ZendInputFilterExceptionInvalidArgumentException:
ZendInputFilterFactory::createInput expects an array or Traversable;
received “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:20FAILURES! Tests: 4, Assertions: 0, Errors: 1.
I undestand, why the error is thrown. Bu how to to resolve this in another way?
In my test, I create a quick class extending the abstract class, then I test the concrete methods in that class.
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);
}
}
After this, you can then use the either a Mock object of the Abstract class created in the test, or mock the Abstract class as you have done.