Zend_Controller_Response_Exception: Cannot send headers;


Zend_Controller_Response_Exception: Cannot send headers;

当运行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: Cannot send headers;头已经发送到/usr/share/php5/pear/phunit/util/printer .php,行173

和作为结果-测试失败

这是因为PHPUnit在测试运行之前就产生了输出。您需要在测试用例中注入一个Zend_Controller_Response_HttpTestCaseZend_Controller_Response_Http的这个子类实际上不发送报头或输出任何东西,并且它不会抛出异常,因为它不关心输出是否已经发送。

只需将以下方法添加到上述类中。

public function setResp(Zend_Controller_Response_Http $resp) {
    $this->_response = $resp;
}

创建一个新的Zend_Controller_Response_HttpTestCase并将其传递给正在测试的对象上的setResp()。这还将允许您验证与输出一起"发送"的报头是否正确。

在我的例子中,我有自定义的请求和响应对象:My_Controller_Request_RestMy_Controller_Response_Rest

为了解决这个问题,我创建了一个新的My_Controller_Request_RestTestCaseMy_Controller_Response_RestTestCase,分别扩展了Zend_Controller_Request_HttpTestCaseZend_Controller_Response_HttpTestCase

David 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

我希望我说得很清楚。我知道这篇文章很老了,但我认为值得再扩展一下。