使用CSRF对ZF2表单进行单元测试的问题


Problems with unit testing ZF2 form with CSRF

我正在尝试对ZF2应用程序进行单元测试。我有一个表格,根据是为学生还是员工而略有变化,我有两个独立的工厂来生产它们。

无论如何,我试着在下面的测试中测试学生表格:

public function testStudentFormAcceptsValidValues()
{
    $this->getEmMock();
    $this->mockLogin('admin');
    $form = $this->serviceManager->get('student_form');
    $this->getApplicationServiceLocator()->setService('student_form', $form);
    $url = '/user/account/add/student';
    $this->dispatch($url);
    $csrf = $form->get('csrf')->getValue();
    $postData = $this->userStubData[1];
    $postData['csrf'] = $csrf;
    $user = new UserEntity();
    $this->getApplicationServiceLocator()->setService('user_entity', $user);
    $this->dispatch($url, 'POST', $postData);
    $this->assertRedirectTo('/user#students');
    $this->assertEntityPropertiesSet($user, $postData);
}

当我运行此测试时,它通过了。然而,我正在为一个员工表单进行类似的测试,但它会失败,因为CSRF令牌是错误的。因此,为了好玩,我决定连续两次进行上述测试,看看会发生什么。它再次失败,原因完全相同。

我最终决定检查两个测试的CSRF令牌值,发现它们都是相同的。出于某种原因,表单重新使用了上一次测试的CSRF值,而不是创建一个新的值,因此表单拒绝了它。

我必须做些什么才能清除旧的CSRF值,并获得表单可以接受的新值?

我不知道你是如何配置测试的,但在测试之间引导应用程序是很常见的,这样你就可以在重新初始化所有服务等的情况下运行第二个测试。

可能您的一些服务在第一次测试中被初始化,而第二次测试则使用第一次测试的"错误"旧值重用已经初始化的服务。