Zend_Controller_Response_Exception: 无法发送标头;

4
在运行Zend应用程序的所有测试时,出现了以下这行代码:
protected function _getResp()
{
    if (is_null($this->_response))
        $this->_response = new Zend_Controller_Response_Http();
    return $this->_response;
}
.......
$this->_getResp()->setHeader('Content-Type', 'text/html; charset=utf-8', true);

产生以下错误:

Zend_Controller_Response_Exception: 无法发送标头,因为标头已经在 /usr/share/php5/PEAR/PHPUnit/Util/Printer.php 的第173行被发送。

因此,测试失败。


请参阅https://dev59.com/N3VC5IYBdhLWcg3wxEJ1,其中介绍了需要发送头信息的项的PHPUnit单元测试。 - Manse
2个回答

3
这是由于PHPUnit在测试运行之前生成输出。您需要在测试用例中注入一个Zend_Controller_Response_HttpTestCase。这个子类Zend_Controller_Response_Http实际上不会发送标头或输出任何内容,并且它不会抛出异常,因为它不关心输出是否已经被发送。
只需将以下方法添加到上述类中即可。
public function setResp(Zend_Controller_Response_Http $resp) {
    $this->_response = $resp;
}

创建一个新的Zend_Controller_Response_HttpTestCase,并将其传递给您正在测试的对象上的setResp()。这还可以让您验证正确的标头随输出一起“发送”了。

我知道这有点老了,但你需要在哪里写这个?我有完全相同的问题,但我不明白从你的答案中应该在哪里写这些代码行,我尝试在主引导程序中以及在ControllerTestCase中,但都没有成功。 - Uffo
你是否正在使用 Zend_Test_PHPUnit_ControllerTestCase?它会在 bootstrap() 中将 Zend_Controller_Response_HttpTestCase 响应注入到前端控制器中。 - David Harkness
我仍然没有看到Uffo的问题的答案(我也有同样的问题)。setResp函数应该放在哪个文件中?我尝试将代码添加到Zend_Test_PHPUnit_ControllerTestCase中,但它没有起作用。 - blainarmstrong
@blainarmstrong - 查看ZF源代码(1.12.1、1.11.10和1.11.0),我找不到_getResp()。在我们的测试框架中,我在PHPUnit引导程序中执行上述操作。但是,您应该能够注入自己的Zend_Controller_Front子类来覆盖getResponse()以返回新的Zend_Controller_Response_HttpTestCase - David Harkness
它对我有用!谢谢,但是有人能解释一下为什么PHPUnit会在测试运行之前生成输出吗? - MengT
@Truman'sworld PHPUnit在运行任何测试之前会输出版本、作者和配置文件位置,同时在运行测试时输出单个测试的状态和完成百分比。这样做是为了让您立即看到结果。 - David Harkness

0
在我的情况下,我有自定义的请求和响应对象:My_Controller_Request_RestMy_Controller_Response_Rest
为了解决这个问题,我创建了一个新的 My_Controller_Request_RestTestCaseMy_Controller_Response_RestTestCase,它们分别扩展了 Zend_Controller_Request_HttpTestCaseZend_Controller_Response_HttpTestCaseDavid Harkness 建议的方法实际上解决了这个问题。唯一的问题是你的对象必须扩展与每个类对应的 HttpTestCase 类。
你需要为每个对象创建 setter,因为你不能直接设置它们。
我有以下的 ControllerTestCase 代码:

tests/application/controllers/ControllerTestCase.php

abstract class ControllerTestCase extends Zend_Test_PHPUnit_ControllerTestCase
{
    /**
     * Application instance.
     * @var Zend_Application
     */
    protected $application;

    /**
     * Setup test suite.
     *
     * @return void
     */
    public function setUp()
    {
        $this->_setupInitializers();
        $this->bootstrap = array(
            $this,
            'applicationBootstrap',
        );
        parent::setUp();

        $this->setRequest(new My_Controller_Request_RestTestCase());
        $this->setResponse(new My_Controller_Response_RestTestCase());
    }
}

我的自定义请求和响应对象具有以下签名:

library/My/Controller/Request/Rest.php

class My_Controller_Request_Rest extends Zend_Controller_Request_Http
{
    // Nothing fancy.
}

library/My/Controller/Response/Rest.php

class Bonzai_Controller_Response_Rest extends Zend_Controller_Response_Http
{
    // Nothing fancy either
}

现在,我无法弄清楚如何避免在library/My/Controller/Request/Rest.phplibrary/My/Controller/Controller/Request/RestTestCase.php中重复相同的代码。在我的情况下,Request/Rest.php和Request/RestTestCase.php以及Response/Rest.php和Response/RestTestCase.php中的代码是相同的,但它们都扩展了Zend_Controller_(Request|Response)_HttpTestCase

我希望我表达清楚了。我知道这篇文章很旧,但我认为值得再深入探讨一下。


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