Zend framework Zend Framework中具有哈希元素的单元测试表单

Zend framework Zend Framework中具有哈希元素的单元测试表单,zend-framework,phpunit,Zend Framework,Phpunit,我试图在我的Zend_表单中测试有效的表单数据,但是它失败了,因为它有一个随机生成的散列元素,我无法访问生成的散列以将其放回断言数据。例如 $form = new MyForm(); $data = array('username'=>'test'); $this->assertTrue($form->isValid($data)); 这失败了,因为它不包含哈希元素值。当我的表单有captcha时,我遇到了同样的问题,我想测试它。我想不出两种可能的解决方案: 首先呈现表单(然

我试图在我的Zend_表单中测试有效的表单数据,但是它失败了,因为它有一个随机生成的散列元素,我无法访问生成的散列以将其放回断言数据。例如

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

这失败了,因为它不包含哈希元素值。

当我的表单有captcha时,我遇到了同样的问题,我想测试它。我想不出两种可能的解决方案:

  • 首先呈现表单(然后将生成散列),然后获取该元素,获取值并使用它来测试表单
  • 只需删除哈希元素进行测试

  • 谢谢单身人士。在测试之前呈现表单非常适合我的问题。我不太乐意删除哈希元素进行测试,因为:

  • 您将添加一定量的 删除这些代码是毫无意义的 测试期间的元素
  • 安全功能也需要测试
  • 下面是我如何做到这一点的一个快速示例:

    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());
    }
    

    我最近发现了一种使用散列元素测试表单的好方法。这将使用一个模拟对象来存根散列元素,您不必担心它。你甚至不需要这样做一个会话启动或任何事情。您也不必“预渲染”表单

    首先像这样创建一个“stub”类

    
    
        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中,您可以更正以下内容

    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 ) ); } 分类我的表格登录测试 扩展PHPUnit_框架_测试用例 { /** * *@var My_Form_登录 */ 受保护的美元形式; /** * *@var PHPUnit\u Framework\u MockObject\u MockObject */ 受保护的$散列; 公共功能设置() { 父::设置(); $this->\u hash=$this->getMock('My\u Form\u Element\u HashStub'); $this->\u form=新的我的表单登录(数组)( “操作”=>“/”, 'hashElement'=>$this->\u哈希 } 公共函数testTrue() { //哈希元素现在将始终验证为true $this->\u散列 ->期望($this->any()) ->方法('isValid') ->威尔($this->returnValue(true)); //或者,如果您需要它验证为false $this->\u散列 ->期望($this->any()) ->方法('isValid') ->威尔($this->returnValue(true)); }

    您必须创建自己的存根。您不能只调用phpunit方法
    getMockObject
    ,因为这将直接扩展散列元素,而普通散列元素在其构造函数中做“邪恶”的事情

    使用这种方法,你甚至不需要连接到数据库来测试你的表单!我花了一段时间才想到这一点

    如果需要,可以将
    setHashElement
    方法(以及变量和get方法)推送到某个FormAbstract基类中

    请记住,在phpunit中,在表单构造过程中必须传递哈希元素。如果不传递,则在使用set方法设置存根哈希之前,将调用init方法,最终将使用常规哈希元素。您将知道您正在使用常规哈希元素,因为如果不传递,可能会出现一些会话错误连接到数据库

    如果您觉得这有帮助或使用它,请告诉我。

    似乎是以下内容的副本: