我正在尝试在我的一个Zend_Forms中测试有效的表单数据,但是由于它具有随机生成的哈希元素而导致它失败,我无法访问生成的哈希将其重新置于断言数据中。 E.g。
$form = new MyForm();
$data = array('username'=>'test');
$this->assertTrue($form->isValid($data));
由于它不包含哈希元素值,因此失败。
答案 0 :(得分:4)
当我的表格有验证码时,我遇到了同样的问题,我想测试一下。我无法思考的两种可能的解决方案:
答案 1 :(得分:3)
谢谢单打。在测试之前渲染表单完全适用于我的问题。我不会太高兴删除哈希元素进行测试:
以下是我如何做到这一点的简单示例:
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());
}
答案 2 :(得分:1)
我最近发现了一种使用哈希元素测试表单的好方法。这将使用模拟对象来删除哈希元素,您不必担心它。你甚至不需要这样做session_start或任何东西。您也不必“预呈现”表格。
首先创建一个'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方法getMockObject
,因为它会直接扩展hash元素,而普通的hash元素会在其构造函数中执行'evil'。
使用此方法,您甚至无需连接到数据库来测试表单!我花了一段时间才想到这一点。
如果需要,可以将setHashElement
方法(以及变量和get方法)推送到某个FormAbstract基类中。
请记住,在phpunit中,您必须在表单构造期间传递哈希元素。如果不这样做,则在使用set方法设置存根哈希之前将调用init方法,并且最终将使用常规哈希元素。你会知道你正在使用常规哈希元素,因为如果你没有连接到数据库,你可能会遇到一些会话错误。
如果您觉得有用或者使用它,请告诉我。