单元测试(PHPUnit):如何登录?

4

我正在为使用Zend Framework的当前项目编写测试。一切都很好,但是我在测试登录用户的操作/控制器时遇到了问题:我需要登录才能执行操作/控制器。

我该如何在PHPUnit中登录?

4个回答

7

根据您的说法,您希望测试操作/控制器,我想您不是在编写单元测试,而是功能/集成测试-即,使用 Zend_Test 并通过MVC进行测试。

这里是我在一个项目中使用的测试函数,我正在测试登录是否正常:

public function testLoggingInShouldBeOk()
{
    $this->dispatch('/login/login');
    $csrf = $this->_getLoginFormCSRF();
    $this->resetResponse();
    $this->request->setPost(array(
        'login' => 'LOGIN',
        'password' => 'PASSWORD',
        'csrfLogin' => $csrf,
        'ok' => 'Login',
    ));
    $this->request->setMethod('POST');
    $this->dispatch('/login/login');
    $this->assertRedirectTo('/');
    $this->assertTrue(Zend_Auth::getInstance()->hasIdentity());
}

简单来说:我正在加载登录表单,提取 CSRF 令牌,填充表单并提交。
然后,我可以测试是否连接成功。
因此,您可能可以提取登录部分,在每个需要已登录有效用户的测试之前调用它。

哇,非常感谢你提供这么快速和好看的答案。我会马上尝试(并在 Google 上查找有关 CSRF 的信息;-)),并随时向您汇报我的结果。 - OSdave
嗯,我在维基百科上读到了有关CSRF的内容,我理解了大致的概念,请纠正我如果我错了:这个CSRF令牌是一个带有标识用户字符串的隐藏输入。 我没有使用这种保护(虽然我可能应该),所以我使用了你的代码,没有包含关于CSRF的2行代码,它运行得非常好! 非常感谢Pascal,再见。 - OSdave
如果您将测试提交到像git或svn这样的版本控制系统中,则需要小心存储用户名和密码。 - Bendihossan

1

还有另一种方法。在我的User实体中,我有一个login()方法,它将用户的ID放入会话和静态变量中。在测试的setUp()中,我只需要调用$user->login()即可。在测试环境中,不使用会话(设置Zend_Session::$isUnitTested = true即可),测试依赖于静态变量。只需记得在tearDown()上清除静态变量(logout()用户)。


嗨Emil, 感谢您的回答。 这很相似,对吧。您介意发布一些相关代码吗?(我指将用户ID放入ZendFramework / PHPUnit会话的部分) 实际上,我有点困惑,我认为这是不可能的,因为PHPUnit不像浏览器那样工作,所以您对此的想法对我来说非常有趣。 - OSdave
抱歉,David,我骗了你。 :) 我查看了代码并编辑了响应。 - Emil Ivanov
好的,我很高兴我的关于会话和单元环境的理解并不完全错误。 目前我会继续使用Pascal的解决方案,但知道还有其他选择也是好的。 谢谢,Emil。 - OSdave

1

我认为这篇文章可能会对您有所帮助: http://perevodik.net/en/posts/7/ 它描述了如何创建一个虚假身份,您可以使用该身份将环境设置为等同于用户已登录的状态。


0

就像Pascal使用这个函数一样:

$this->_getLoginFormCSRF();

我创建了一个通用函数,通过使用表单元素管理器加载表单来返回值:
``` public function _getCSRFHashValueFromForm($formAlias, $csrfName) { $form = $this->servicemanager->get('FormElementManager')->get($formAlias); return $form->get($csrfName)->getValue(); } ```
当然,这假设CSRF绑定到表单而不是任何字段集中等。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接