2015-05-04 62 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_。如果你想把它放到自動化的構建/部署中,它肯定會變得更加複雜,但絕對可行。