2015-04-02 130 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(); 

}