Модульные тестовые формы, которые имеют хеш-элемент в Zend Framework - PullRequest
3 голосов
/ 22 февраля 2011

Я пытаюсь проверить действительные данные формы в одной из моих Zend_Forms, однако это не удается из-за наличия хеш-элемента, который генерируется случайным образом, и я не могу получить доступ к сгенерированному хешу, чтобы вернуть его обратно в данные утверждения.Например,

$form = new MyForm();
$data = array('username'=>'test');
$this->assertTrue($form->isValid($data));

Сбой, поскольку он не содержит значения элемента хеша.

Ответы [ 3 ]

4 голосов
/ 22 февраля 2011

У меня была такая же проблема, когда в моей форме была капча, и я хотел ее проверить. Два возможных решения, о которых я не могу думать:

  1. Сначала визуализируйте форму (затем будет сгенерирован хеш), затем возьмите этот элемент, примите значение и используйте его для проверки формы.
  2. Просто удалите хеш-элемент для тестирования.
3 голосов
/ 15 марта 2011

Спасибо знакомств.Рендеринг формы перед тестированием отлично сработал для моей проблемы.Я не был бы слишком рад удалить элемент хеша для тестирования как:

  1. Вы будете добавлять определенное количество бессмысленного кода для удаления этих элементов во время тестирования.
  2. Безопасностьфункции тоже нужно протестировать.

Вот краткий пример того, как я это сделал:

public function testLoginSetsSession()
{
    // must render the form first to generate the CSRF hash
    $form = new Form_Login();
    $form->render();

    $this->request
         ->setMethod('POST')
         ->setPost(array(
             'email' => 'test@test.co.uk',
             'password' => 'password',
             'hash' => $form->hash->getValue()
         ));
    $this->dispatch('/login');

    $this->assertTrue(Zend_Auth::getInstance()->hasIdentity());
}
1 голос
/ 26 апреля 2012

Недавно я нашел отличный способ тестирования форм с элементами хеша.Это будет использовать фиктивный объект, чтобы заглушить хеш-элемент, и вам не придется беспокоиться об этом.Вам даже не нужно будет делать session_start или что-то подобное.Вам также не нужно «предварительно» представлять форму.

Сначала создайте класс-заглушку, например, так:



    class My_Form_Element_HashStub extends Zend_Form_Element_Hash
    {
        public function __construct(){}
    }


Затем добавьте в форму следующее:


    class MyForm extends Zend_Form{

    protected $_hashElement;

    public function setHashElement( Zend_Form_Hash_Element $hash )
    { 
      $this->_hashElement = $hash; 
      return $this; 
    }

    protected function _getHashElement( $name = 'hashElement' )
    { 
      if( !isset( $this->_hashElement )
      {
          if( isset( $name ) )
          {
                $element = new Zend_Form_Element_Hash( $name, 
                                                      array( 'id' => $name ) );
          }
          else
          {
                $element = new Zend_Form_Element_Hash( 'hashElement', 
                                            array( 'id' => 'hashElement' ) );
          }

         $this->setHashElement( $element );
         return $this->_hashElement;
      }
    }
    /**
     *
     * In your init method you can now add the hash element like below
     *
     *
     *
     */

    public function init()
    {
        //other code
        $this->addElement( $this->_getHashElement( 'myotherhashelementname' );
        //other code
    }

Метод set существует только для тестирования.Вы, вероятно, вообще не будете использовать его во время реального использования, но теперь в phpunit вы можете исправить следующее:

</p> <pre> class My_Form_LoginTest extends PHPUnit_Framework_TestCase { /** * * @var My_Form_Login */ protected $_form; /** * * @var PHPUnit_Framework_MockObject_MockObject */ protected $_hash; public function setUp() { parent::setUp(); $this->_hash = $this->getMock( 'My_Form_Element_HashStub' ); $this->_form = new My_Form_Login( array( 'action' => '/', 'hashElement' => $this->_hash } public function testTrue() { //The hash element will now always validate to true $this->_hash ->expects( $this->any() ) ->method( 'isValid' ) ->will( $this->returnValue( true ) ); //OR if you need it to validate to false $this->_hash ->expects( $this->any() ) ->method( 'isValid' ) ->will( $this->returnValue( true ) ); } </pre> <p>

У вас ДОЛЖЕН быть свой собственный заглушку.Вы не можете просто вызвать метод phpunit getMockObject, потому что это непосредственно расширит элемент хеша, а обычный элемент хеша делает «злые» вещи в своем конструкторе.

С этим методом вам даже не нужно подключаться к базе данных для проверки ваших форм!Мне понадобилось время, чтобы подумать об этом.

Если вы хотите, вы можете вставить метод setHashElement (вместе с переменной и методом get) в некоторый базовый класс FormAbstract.

REMEMBER, в phpunit вы ДОЛЖНЫ передать хешэлемент при создании формы.Если вы этого не сделаете, ваш метод init будет вызван до того, как ваш хэш заглушки может быть установлен с помощью метода set, и вы в конечном итоге будете использовать обычный элемент хеша.Вы будете знать, что используете обычный элемент хеширования, потому что, возможно, у вас возникнет ошибка сеанса, если вы НЕ подключены к базе данных.

Дайте мне знать, если вы найдете это полезным или используете его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...