Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Zend 2: Unit tests for form class

I'm just starting using PHPUnit with Zend and need little help to figure out how these tests should work.

I want to test if form return any error message if I do not pass any POST parameters.

The problem is that one field from my form is using Doctrine's DoctrineModule\Form\Element\ObjectSelect

    ...
    $this->add(array(
        'type' => 'DoctrineModule\Form\Element\ObjectSelect',
        'name' => 'user',
        'attributes' => array(
            'id' => 'user-label',
        ),
        'options' => array(
            'object_manager' => $em,
            'target_class' => 'Application\Entity\User',
            'property' => 'username',
            'label' => 'User:',
            'display_empty_item' => true,
            'empty_item_label'   => '---',
            'label_generator' => function($entity) {
                return $entity->getUsername();
            },
        ),
    ));
    ...

I get following error:
Fatal error: Call to a member function getIdentifierFieldNames() on null

I tried override this field with mocked object, however Zend doesn't allow objects in type, just class name (string), so this code doesn't work:

public function testIfFormIsValid()
{
    $objectSelect = $this->getMockBuilder('DoctrineModule\Form\Element\ObjectSelect')
        ->disableOriginalConstructor()
        ->getMock();
    $objectSelect->expects($this->any())
        ->method('getValueOptions')
        ->will($this->returnValue(array()));

    $form = new \AppModuleComment\Form\Comment('form', array(
        'em' => $this->em  // Mocked object
    ));
    $form->add(array(
        'type' => $objectSelect,
        'name' => 'user',
        'attributes' => array(
            'id' => 'user-label',
        ),
        'options' => array(
            'object_manager' => $this->em,
            'target_class' => 'Application\Entity\User',
            'property' => 'username',
            'label' => 'User:',
            'display_empty_item' => true,
            'empty_item_label'   => '---',
            'label_generator' => function($entity) {
                return $entity->getUsername();
            },
        ),
    ));

    $data = array(
        'id' => null,
        'user' => null
    );

    $form->setData($data);
    $this->assertTrue($form->isValid(), 'Form is not valid');
}    

What am I doing wrong? How should I test such code?

like image 586
user1409508 Avatar asked Sep 05 '16 10:09

user1409508


1 Answers

It seems you are testing functionality of Zend or Doctrine (or both) and not your own code. When you use libraries you should trust these libraries.

What happens is: Form\Form::add() uses Form\Factory::create() to create from the array an element. Form\Factory::create() uses Form\FormElementManager::get() to get an element from the given type.

Your type is an object and because Form\FormElementManager::get() can not handle objects your script will fail.

It seems you want to test that if post is empty Form::valid() calls ObjectSelect::valid() but this does not verify if the value is null. That's code from Doctrine / Zend not yours. Don't test it.

More interesting it gets when you want to mock the result of an select from within Doctrines ObjectSelect. But that's another question.

like image 164
iRaS Avatar answered Oct 23 '22 02:10

iRaS