2012-07-16 197 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