2015-04-02 128 views
1

我正在使用嵌入式控制器在側面模板中生成動態內容(例如:菜單)如何用phpunit測試symfony2嵌入式控制器?

通常,我執行函數測試來斷言控制器。 到目前爲止,functionnal測試通過,phpunit認爲我的嵌入式控制器代碼覆蓋

我想知道如何測試嵌入式控制器不同的輸入和評估輸出......是單元測試的權利?

我知道單元測試控制器是一個不好的做法,但是如何在沒有請求對象時測試嵌入式控制器? 路由/ url是Twig render()函數處理的內容。

{{ render(controller('AppSuperBundle:Default:generateMenu', {'params': ... })) }}

一個例子來說明:

class DefaultController extends Controller 
{ 
    public function testAction() 
    { 
     return $this->render('AppSuperBundle::index.html.twig'); 
    } 

    public function generateMenuAction($route, Array $RouteParams) 
    { 
     $repo = $this->getDoctrine()->getRepository(... 
     //some process to generate params of menu items (eg:locale, url, name...) 

     return $this->render('AppSuperBundle::menu.html.twig', array('menuItems' => $menuItemsWithParams)); 
    } 
} 

模板index.html.twig

<html> 
    <body> 
     {% block menu %} 
     {{ render(controller('AppSuperBundle:Default:generateMenu', {'route': app.request.attributes.get('_route'), 'RouteParams': app.request.attributes.get('_route_params')})) }} 
     {% endblock %} 
     {% block content %} 
     ... 
     {% endblock %} 
    </body> 
</html> 

你對這個想法?

+0

我想,一般你不應該試圖以這種方式嵌入控制器的輸出。你有沒有檢出https://github.com/KnpLabs/KnpMenuBundle? – nateevans 2015-04-02 21:19:42

+0

感謝您的評論。我使用原則,可翻譯,sluggable和樹來生成我的i18n超鏈接。據我所知,KnpMenuBundle只使用翻譯文件。我的代碼很明確,只使用一個控制器函數和一個模板,所以我沒有看到需要實現一個服務並對其進行自定義。嵌入式控制器應該如何實現? – x0s 2015-04-03 08:10:54

+0

在我與Symfony核心成員和主要文檔編寫人員Ryan Weaver的培訓中,他通常不鼓勵我以非標準方式使用控制器作爲約定。但是我試圖做一些事情,比如從另一個Controller中調用Controller。壞juju。回到你原來的問題,我認爲你可以測試你的嵌入式控制器所在的路線。請參閱http://symfony.com/doc/current/book/testing.html#your-first-functional-test。您可以傳遞不同的參數,並根據您的請求使用搜尋器查找預期的輸出 – nateevans 2015-04-06 19:26:02

回答

0

您的嵌入式控制器不存在於真空中。它們正在被主控制器中使用的模板加載。

我會說只檢查主控制器就足夠了。如果你真的想檢查嵌入式控制器的不同輸出,只需用適當的參數測試主控制器即可。最後,主控制器將爲您的嵌入式控制器帶來不同的價值。

0

由於渲染視圖是響應,並且您正在討論單元測試,所以我強烈建議對控制器進行單元測試,因爲在某些項目中,控制器可能會有很多邏輯。 我會單元測試一個控制器的行爲,所以它不會從控制器中的代碼中拋出奇怪的錯誤。所以我建議你做的是對每一個動作每一種情況下創建一個測試方法,你可能會需要模擬一些控制器使用的對象,這裏有一個例子:

public function testIndexAction() 
{ 
    $this->employeeRepository->expects($this->once())->method('findByFilter')->will($this->returnValue($this->employee)); 
    $this->entityManager->expects($this->once())->method('getRepository')->will(
     $this->returnValue($this->employeeRepository) 
    ); 


    $this->employeeManager->expects($this->once())->method('formatEmployeeData')->will(
     $this->returnValue($this->formattedJson) 
    ); 


    $this->mockContainer($this->object); 

    $this->object->indexAction(); 

}