【问题标题】:Symfony unit testing & the containerSymfony 单元测试和容器
【发布时间】:2012-07-16 22:32:57
【问题描述】:

在 Symfony 2 中进行单元测试时,我正在测试的控制器没有接收到服务容器,导致测试失败并使用旧的 Call to a member function get() on a non-object

我不能从测试控制器使用 $this->forward,因为它也没有服务容器。

我找到了这个参考,但似乎我会因为错误的原因使用它,有没有人有这方面的经验?

http://symfony.com/doc/current/book/testing.html#accessing-the-container

编辑:这是我的测试:

<?php

namespace HvH\ClientsBundle\Tests\Controller;

use HvH\ClientsBundle\Controller\ClientsController;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\HeaderBag;
use Symfony\Component\HttpFoundation\Session;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class ClientsControllerTest extends WebTestCase
{

    public function testGetClientsAction()
    {

        $client = static::createClient();
        $container = $client->getContainer();
        $session = $container->get('session');
        $session->set('key', 'value');
        $session->save();

        $request = new Request;
        $request->create('/clients/123456', 'GET', array(), array(), array(), array(), '');

        $headers['X-Requested-With'] = "XMLHttpRequest";
        $request->headers->add($headers);

        /* This doesn't work */
        /*
        $controller = new Controller;
        $status = $controller->forward( 'HvHClientsBundle:Clients:getClients', array('request' => $request) );        
        */

        $clients_controller = new ClientsController();
        $status = $clients_controller->getClientsAction($request);

        $this->assertEquals(200, $status);
    }

}

这是失败的客户端控制器部分

<?php

namespace HvH\ClientsBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use HvH\APIschemaBundle\Controller\Validation;


//FOSRestBundle
use FOS\RestBundle\View\View;

class ClientsController extends Controller
{

    //Query all clients
    public function getClientsAction(Request $request)
    {
        $request_type = $request->headers->get('X-Requested-With');

        if($request_type != 'XMLHttpRequest') {
            return $this->render('HvHDashboardBundle:Dashboard:dashboard.html.twig' );          
        }

        //get any query strings
        $query_strings = $request->query->all();
        $definition = $this->get("service.handler")->definition_handler(__CLASS__, __FUNCTION__);
        //once data has been prepared 
        return $this->get('fos_rest.view_handler')->handle($view);

    }    
}

【问题讨论】:

  • 能否提供一个测试类的最小示例,包括声明和尝试使用容器的方法?
  • 感谢您的回复,我已经更新了测试示例和正在测试的控制器。它在自定义服务行失败$definition = $this-&gt;get("service.handler")-&gt;definition_handler(__CLASS__, __FUNCTION__);
  • 控制器没有获取容器的原因是因为您试图直接实例化并与之交互,而不是使用 $client 来发出请求。我可以给你一个例子,但我有点困惑为什么 getClientsAction 将请求作为参数。是对该请求对象执行的操作,还是您可以改为使用“$request = $this->get('request');”获取请求通常在 Controller 的子类中完成?
  • 我已经从参数中取出了请求,并像你说的那样添加了它。如果你能给我举个例子那就太好了!
  • 是否也可以看到 getClientsAction() 的路由定义?

标签: symfony phpunit


【解决方案1】:

我认为控制器没有获取容器的原因是因为您尝试直接实例化并与之交互,而不是使用客户端模拟请求(请参阅 Symfony2 书的Testing section 中的功能测试部分)。

你需要更多这样的东西(不确定路线是否正确):

public function testGetClientsAction()
{
    $client = static::createClient();

    $client->request(
        'GET', '/clients/123456', 
        array(), /* request params */ 
        array(), /* files */
        array('X-Requested-With' => "XMLHttpRequest"),
    );

    $this->assertEquals(200, $client->getResponse()->getStatusCode());  
}

另请注意,request() 方法返回一个爬虫实例,该实例提供辅助方法来验证响应的内容(如果需要)。

【讨论】:

  • 很好的答案!谢谢!看起来很有希望,但现在我正在重定向到登录,我相信我可以自己解决这个问题,但如果你有一个方便的链接,那就太好了。
  • 这个链接成功了验证:symfony.com/doc/current/cookbook/testing/…
猜你喜欢
  • 2012-02-16
  • 1970-01-01
  • 2018-08-03
  • 2019-06-04
  • 2011-04-27
  • 1970-01-01
  • 2017-03-19
  • 1970-01-01
  • 2020-07-07
相关资源
最近更新 更多