如何对包含 CSRF 表单元素的 Zend_Form 进行单元测试?
我将 CSRF 隐藏哈希元素与 Zend_Form 一起使用,并尝试对登录进行单元测试,但不知道如何编写单元测试来包含该元素。 查看文档并阅读尽可能多的教程。 我什至把它们都吃了,但没有人提到这一点。
I'm using the CSRF hidden hash element with Zend_Form and trying to Unit Test the login but don't know how to write a Unit Test to include that element. Looked in the docs and read as many tutorials as I could find. I even delicioused them all, but no one mentions this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
每次渲染表单时都会生成 Csrf 值。 表单的隐藏元素会预先填充该值。 该值也存储在会话中。
提交表单后,验证会检查从表单发布的值是否存储在会话中,如果没有,则验证失败。 至关重要的是,在测试期间必须渲染该表单(这样它就可以生成隐藏值并将其存储到会话中),然后我们可以从渲染的html中提取隐藏值,然后我们可以将隐藏的哈希值添加到我们的要求。
考虑这个例子:
Csrf value is generated each time form is rendered. Hidden element of the form gets prefilled with that value. This value also gets stored in session.
After submitting form, validation checks if value posted from the form is stored in session, if not then validation fails. It is essential, that form must be rendered during the test (so it can generate the hidden value and store it to session), then we can extract what is the hidden value out of rendered html, and later we can add hidden hash value into our request.
Consider this example:
正确的散列存储在会话中,并且 Hash 表单元素有一个 Zend_Session_Namespace 实例,其中包含散列的命名空间。
要对元素进行单元测试,您可以将元素中的 Zend_Session_Namespace 实例(使用 setSession)替换为您自己创建的包含正确散列的实例(散列存储在键“hash”中)
有关更多示例,您可以查看 Zend Zend_Form_Element_Hash 类的框架单元测试。 我认为他们也必须处理这个问题。
The correct hash is stored in the session, and the Hash form element has a Zend_Session_Namespace instance which contains the namespace for the hash.
To unit test the element, you would replace the Zend_Session_Namespace instance in the element (with setSession) with one you create yourself which contains the correct hash (the hash is stored in key "hash")
For further examples you could probably look at the Zend Framework unit tests for the Zend_Form_Element_Hash class. I would assume they have had to deal with this as well.
我在 Apache vhost 文件中设置了一个环境变量,它告诉代码它正在哪个服务器上运行:
开发、登台或生产
vhost 文件的行是:
然后我只是让我的表单对适当的环境做出反应:
我对很多东西使用相同的技术。 例如,如果是开发人员,我会将所有外发电子邮件重定向给我,等等。
I set an environment variable in my Apache vhost file, which tells the code which server it's running on:
development, staging, or production
The line for the vhost file is:
Then I just make my forms react to the appropriate environment:
I use this same technique for lots of stuff. For example, if it IS dev, I redirect all outgoing email to me, etc.
我最近回答了一个与此类似的问题。 我也将我的答案放在这里,以防将来对任何人有帮助。
我最近发现了一种使用哈希元素测试表单的好方法。 这将使用模拟对象来消除哈希元素,您不必担心它。 您甚至不必以这种方式执行 session_start 或任何操作。 您也不必“预渲染”表单。
首先创建一个像这样的“存根”类
然后,将以下内容添加到表单的某处。
set 方法实际上只是用于测试目的。 在实际使用过程中您可能根本不会使用它,但现在在 phpunit 中您可以纠正以下内容。
您必须创建自己的存根。 您不能只调用 phpunit 方法
getMockObject()
因为这将直接扩展哈希元素,而普通哈希元素在其构造函数中会做“邪恶”的事情。使用这种方法,您甚至不需要连接到数据库来测试您的表单! 我花了一段时间才想到这一点。
如果需要,您可以将
setHashElement()
方法(以及变量和 get 方法)推送到某个 FormAbstract 基类中。请记住,在 phpunit 中,您必须在表单构建期间传递哈希元素。 如果不这样做,您的
init()
方法将在使用 set 方法设置存根哈希之前被调用,并且您最终将使用常规哈希元素。 您会知道您正在使用常规哈希元素,因为如果您未连接到数据库,您可能会收到一些会话错误。如果您觉得这有帮助或者您正在使用它,请告诉我。
I answered a more recent question similar to this one. I'm putting my answer here as well in case it helps anybody in the future.
I recently found a great way of testing forms with hash elements. This will use a mock object to stub away the hash element and you won't have to worry about it. You won't even have to do a session_start or anything this way. You won't have to 'prerender' the form either.
First create a 'stub' class like so
Then, add the following to the form somewhere.
The set method is there just for testing purposes really. You probably won't use it at all during real use but now in phpunit you can right the following.
You HAVE to create your own stub. You can't just call the phpunit method
getMockObject()
because that will directly extend the hash element and the normal hash element does 'evil' stuff in its constructor.With this method you don't even need to be connected to a database to test your forms! It took me a while to think of this.
If you want, you can push the
setHashElement()
method ( along with the variable and the get method ) into some FormAbstract base class.REMEMBER, in phpunit you HAVE to pass the hash element during form construction. If you don't, your
init()
method will get called before your stub hash can be set with the set method and you'll end up using the regular hash element. You'll know you're using the regular hash element because you'll probably get some session error if you're NOT connected to a database.Let me know if you find this helpful or if you use it.
ZF2 的解决方案是在测试中创建表单,并从 csrf 表单元素中获取值:
Solution for ZF2 is creating your form in test, and getting value from your csrf form element: