2012-07-16 199 views
3

当Symfony的2单元测试,控制我的测试没有收到服务容器导致测试失败,历久弥新Call to a member function get() on a non-objectSymfony的单元测试和容器

我无法使用$这 - >从测试控制器转发,因为它也没有服务容器。

我发现这个参考,但它似乎好像我会使用它的原因是错误的,有没有人有这方面的经验?

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); 

    }  
} 
+0

是否可以提供测试类的最小示例,包括声明和尝试使用容器的方法? – redbirdo 2012-07-17 16:33:19

+0

感谢您的回应,我更新了测试示例和正在测试的控制器。它在自定义服务行'$ definition = $ this-> get(“service.handler”) - > definition_handler(__ CLASS__,__ FUNCTION __)失败;' – greg 2012-07-17 17:54:46

+0

控制器没有获取容器的原因是因为您试图实例化并直接与其交互,而不是使用$ client发出请求。我可以给你一个例子,但我有点困惑,为什么getClientsAction将一个请求作为参数。请求操作是在这个请求对象上运行还是你可以使用“$ request = $ this-> get('request');”通常在Controller的子类中完成? – redbirdo 2012-07-17 19:19:21

回答

4

我想原因控制器ISN获取容器是因为你试图直接实例化和交互,而不是模拟请求(请参阅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()方法返回一个履带式实例提供辅助方法来验证响应的内容如果需要。

+1

自动处理很好的答案!谢谢!看起来有希望,但现在我重定向到登录,我确信我可以自己找出这一个,但如果你有一个方便的链接,这将是伟大的。 – greg 2012-07-17 19:54:38

+1

此链接为auth做了一些技巧:http://symfony.com/doc/current/cookbook/testing/http_authentication.html – greg 2012-07-17 20:05:20