CakePHP 3.4.2测试POST的响应总是返回NULL

时间:2017-03-15 16:56:51

标签: cakephp integration-testing cakephp-3.4

我正在测试一个只按给定ID搜索记录的应用。 它工作正常,但测试拒绝在代码中返回响应。奇怪的是,它只在CLI中显示。

我正在使用cakephp提供的phpunit:

  

“phpunit / phpunit”:“^ 5.7 | ^ 6.0”

以下是相互冲突的代码:

 $this->post('/comunas/findByBarrio',[
        'barrio_id'=>1
 ]);
 var_dump($this->_response->body());die(); //This is just a test which always returns NULL... while the CLI shows the actual response, which is a JSON.

在对任何其他操作执行GET或POST时也会出现同样的问题。 但这是目标控制器的代码:

public function findByBarrio()
{
    $this->autoRender = false;
    if ($this->request->is('POST'))
    {
        $data = $this->request->getData();
        if (!empty($data['barrio_id']))
        {
            $this->loadModel('Comuna');

            $barrio_id = $data['barrio_id'];

            $comuna = $this->Comuna->find('list',['conditions' => ['barrio_id'=>$barrio_id]])
                ->hydrate(false)
                ->toArray();
            if ($comuna)
            {
                echo json_encode($comuna);
            }
            else
            {
                throw new NotFoundException('0');
                //echo 0; //Comuna no encontrada para el barrio recibido
            }               
        }
        else
        {
            echo -1;
        }
    }
}

提前谢谢!

UPDATE 1 :我只是通过在“$ this-> post”方法周围使用“ob_start()”和“ob_get_clean()”来获取输出。我希望有一个更清洁的方式......

更新2 :现在它正在运作!只需使用符合PSR-7标准的接口即可。谢谢! 这是更正后的控制器:

public function findByBarrio()
{
    $this->autoRender = false;

    $this->response = $this->response->withType('json'); //CORRECTION

    if ($this->request->is('POST'))
    {
        $data = $this->request->getData();
        if (!empty($data['barrio_id']))
        {
            $this->loadModel('Comuna');

            $barrio_id = $data['barrio_id'];

            $comuna = $this->Comuna->find('list',['conditions' => ['barrio_id'=>$barrio_id]])
                ->hydrate(false)
                ->toArray();
            if ($comuna)
            {
                $json = json_encode($comuna);

                $this->response->getBody()->write($json); //CORRECTION

            }
            else
            {
                //Comuna no encontrada para el barrio recibido
                $this->response->getBody()->write(0); //CORRECTION
            }               
        }
        else
        {
            //No se recibió el barrio
            $this->response->getBody()->write(-1); //CORRECTION
        }
    }

    return $this->response; //CORRECTION
}

1 个答案:

答案 0 :(得分:1)

控制器操作不应该回显数据,即使它可能在某些情况下工作,甚至可能在大多数情况下工作。输出不受渲染视图模板影响的数据的正确方法是配置和返回响应对象,或者使用序列化视图。

测试环境依赖于正确执行此操作,因为它不会缓冲可能的输出,但会使用从控制器操作返回的实际值。

以下内容基本上是 https://stackoverflow.com/a/42379581/1392379

的副本

来自文档的引用:

  

控制器操作通常使用Controller::set()来创建View用于呈现视图层的上下文。由于CakePHP使用的约定,您无需手动创建和呈现视图。相反,一旦控制器动作完成,CakePHP将处理渲染并提供视图。

     

如果由于某种原因您想跳过默认行为,则可以使用完全创建的响应从操作中返回Cake\Network\Response对象。

*自3.4起\Cake\Http\Response

<强> Cookbook > Controllers > Controller Actions

配置响应

使用符合PSR-7的界面

$content = json_encode($comuna);

$this->response->getBody()->write($content);
$this->response = $this->response->withType('json');
// ...

return $this->response;

符合PSR-7的接口使用不可变方法,因此使用withType()的返回值。与设置标题和内容不同,通过写入现有流来更改正文并不会更改响应对象的状态。

CakePHP 3.4.3将添加一个不可变的withStringBody方法,可以替代写入现有流。

$this->response = $this->response->withStringBody($content);

使用已弃用的接口

$content = json_encode($comuna);

$this->response->body($content);
$this->response->type('json');
// ...

return $this->response;

使用序列化视图

$content = json_encode($comuna);

$this->set('content', $content);
$this->set('_serialize', 'content');

这还需要使用请求处理程序组件,并启用扩展解析并使用附加了.json的响应URL,或者使用application/json接受标头发送正确的请求。

另见