2015-05-04 30 views
1

在Symfony 2.6/PhpUnit 4.6环境中,我正在寻找一种方法来单独测试一个单一的请求,在该请求可能在稍后阶段调用的情况下例如渲染模板)一个子请求。面向子请求的场景中的Symfony功能测试

具体地,给出下面的页控制器

namespace AppBundle\Controller; 

class Page extends Controller{ 

    public function viewAction(){ 
     return ... 
    } 

} 

这会使包含以下行的一个枝条模板,这将调用的子请求到Widget控制器:

{{ render(controller('AppBundle:Widget:footerLatest')) }} 

Widget控制器有它自己的逻辑,也许它是从数据库中拉出一些东西:

namespace AppBundle\Controller; 

class Widget extends Controller{ 

    public function footerLatestAction(){ 
     $foo = $this->getDoctrine()->getRepository('ModelBundle:Foo')->findBy(...); 

     return [ 
      'foo' => $foo 
     ]; 
    } 

} 

在我的Page控制器功能测试,我会嘲笑主义依赖

namespace AppBundle\Tests\Controller; 

class PageControllerTest extends \Tests\TestCase{ 

    public function testDetailsView(){ 
     $someMock = $this->getMockBuilder('ModelBundle\Entity\SomeEntity') 
       ->getMock(); 
     $entityManagerMock = $this->getMockBuilder('Doctrine\ORM\EntityManager') 
       ->setMethods(array('persist', 'flush', 'getRepository', 'clear')) 
       ->disableOriginalConstructor() 
       ->getMock(); 
     $repositoryMock = $this->getMockBuilder('ModelBundle\Repository\SomeEntityRepository') 
       ->setMethods(['findOneBy', 'findBy']) 
       ->disableOriginalConstructor() 
       ->getMock(); 

     $client->getContainer()->set('doctrine.orm.default_entity_manager', $entityManagerMock); 
     ... 

    } 

} 

此时的问题是清楚的:在每个控制器的测试,我会让我必须考虑到所有的子请求它可能会调用,而这个东西会雪球到可能看起来很糟糕的地方。

我的想法是,我可以安全地认为每个请求(主或子)应被视为完全不同的东西,并且因此明显地测试,即Page控制器将具有PageControllerTest这将调用子请求(它根本不会与任何子请求有关),即使它通常会。而Widget控制器将拥有自己的WidgetControllerTest

那么,如何在功能测试中“禁用/忽略”子请求呢?还是有更好的方法?

回答

0

如果您正在测试控制器,那么请求背后的整个逻辑必须工作。它不再是一个真正的单元测试,而是一个功能测试。所有人都必须工作。不只是请求的一小部分。

如果你有一个简单的数据库,并没有使用任何驱动程序特定的东西,你可以随时切换到内存SQLite数据库。 编辑您的config_test.yml这样的:

doctrine: 
    dbal: 
     default_connection: default 
     connections: 
      default: 
       driver: pdo_sqlite 
       memory: true 

而你所需要的测试数据预填充数据库。

如果你不能使用SQLite,你总是可以配置一个真实的DB,例如,前缀为test_。如果你想把它放到自动化的构建/部署中,它肯定会变得更加复杂,但绝对可行。