如何为FilePostRedirectGet表单提交编写集成测试?
为FilePostRedirectGet表单编写集成测试的解决方案
使用FPRG模式后,表单提交的流程变成了两次重定向:第一次是POST提交后重定向回原页面(把POST数据存在会话里),第二次是原页面GET请求时验证数据,通过后再重定向到编辑页。这确实会打破原来单次dispatch的测试逻辑,不过我们可以通过手动追踪重定向流程来完成测试。
测试成功提交的完整流程
我们需要分两步模拟用户的提交流程:先发送POST请求触发FPRG重定向,再跟随这个重定向发送GET请求,最终验证是否跳转到编辑页。
这里是修改后的测试代码示例(适配Zend Framework的PHPUnit集成测试):
/** * 验证FPRG模式下,合法表单提交后正确跳转到编辑页 */ public function testAddActionRedirectsAfterValidPostWithFPRG() { // 准备合法的表单提交数据(包含文件上传模拟) $postData = $this->_postData(); // 注意:模拟文件上传需要按PHP的文件数组格式构造 $postData['your_file_field'] = [ 'tmp_name' => sys_get_temp_dir() . '/test_upload.jpg', 'name' => 'test_upload.jpg', 'type' => 'image/jpeg', 'size' => 1024, 'error' => UPLOAD_ERR_OK ]; // 第一步:发送POST请求,触发FPRG的第一次重定向 $this->dispatch('http://localhost/admin/cms/add', 'POST', $postData); $this->assertResponseStatusCode(302); // 获取FPRG重定向回原页面的URL $fprgRedirectUrl = $this->getResponse()->getHeaders()->get('Location')->getUri(); // 第二步:跟随重定向发送GET请求,此时FPRG会从会话中取出POST数据验证 $this->dispatch($fprgRedirectUrl); $this->assertResponseStatusCode(302); // 验证最终跳转到目标编辑页 $this->assertRedirectTo('http://localhost/admin/cms/edit/13'); return $postData; }
验证失败场景的测试
除了成功提交,我们还要测试验证失败的情况:此时第二次GET请求不会跳转到编辑页,而是返回带错误提示的表单页面,同时保留文件输入的状态。
/** * 验证FPRG模式下,非法表单提交后正确显示错误信息 */ public function testAddActionShowsErrorsAfterInvalidPostWithFPRG() { // 构造非法数据(比如缺少必填字段) $invalidPostData = array_merge($this->_postData(), ['required_title' => '']); // 同样模拟文件上传 $invalidPostData['your_file_field'] = [ 'tmp_name' => sys_get_temp_dir() . '/test_upload.jpg', 'name' => 'test_upload.jpg', 'type' => 'image/jpeg', 'size' => 1024, 'error' => UPLOAD_ERR_OK ]; // 第一步:发送非法POST请求,触发FPRG重定向 $this->dispatch('http://localhost/admin/cms/add', 'POST', $invalidPostData); $this->assertResponseStatusCode(302); $fprgRedirectUrl = $this->getResponse()->getHeaders()->get('Location')->getUri(); // 第二步:跟随重定向,验证页面返回表单并显示错误 $this->dispatch($fprgRedirectUrl); $this->assertResponseStatusCode(200); // 断言错误信息存在 $this->assertQueryContentContains('.form-error', '标题为必填项'); // 验证文件输入框依然存在(确保状态保留) $this->assertQueryExists('input[type="file"][name="your_file_field"]'); }
关键注意事项
- 会话保持:确保测试环境中会话功能正常启用,因为FPRG依赖会话存储POST数据。如果你的测试框架默认禁用会话,需要手动开启(比如Zend Framework中可以通过
$this->getApplicationServiceLocator()->get('SessionManager')初始化)。 - 不要自动跟随重定向:大多数测试框架的
dispatch方法不会自动跟随重定向,这正好符合我们的需求——需要手动处理两次重定向的流程。 - 文件上传模拟:测试文件上传时,必须严格按照PHP的
$_FILES数组格式构造数据,否则FPRG插件无法正确处理文件。
内容的提问来源于stack exchange,提问作者Richard Parnaby-King
相关产品推荐
相关产品推荐

