簡體   English   中英

如何對Symfony控制器進行單元測試

[英]How to unit test Symfony controllers

我正在嘗試使用Codeception在測試工具中獲取Symfony控制器。 每個方法都從如下開始:

public function saveAction(Request $request, $id)
{
    // Entity management
    /** @var EntityManager $em */
    $em = $this->getDoctrine()->getManager();

    /* Actual code here
    ...
    */
}

public function submitAction(Request $request, $id)
{
    // Entity management
    /** @var EntityManager $em */
    $em = $this->getDoctrine()->getManager();

    /* 200+ lines of procedural code here
    ...
    */
}

我試過了:

$request = \Symfony\Component\HttpFoundation\Request::create(
    $uri, $method, $parameters, $cookies, $files, $server, $content);

$my_controller = new MyController();
$my_controller->submitAction($request, $id);

從我的單元測試,但似乎有很多其他設置,我不知道Symfony在后台做了什么。 每當我找到一個丟失的對象並對其進行初始化時,就會有另一個在某個時刻失敗。

我也試過從PhpStorm中逐步完成測試,但是PhpUnit有一些輸出會導致Symfony在我試圖測試的代碼附近死掉之前因為它在任何輸出發生后都無法啟動$_SESSION 我不認為這是從命令行發生的,但我還不是很接近。

如何在單元測試中簡單且可擴展地運行此代碼?


一點背景:

我繼承了這段代碼。 我知道它很臟並且聞起來因為它在控制器中進行模型邏輯。 我知道我所要求的並不是一個“純粹的”單元測試,因為它幾乎涉及整個應用程序。

但我需要能夠自動運行這個“小”(200+行)的代碼。 代碼應該運行不超過幾秒鍾。 我不知道多久,因為我從來沒有能夠獨立運行它。

目前,通過網站運行此代碼的設置時間很長,而且很復雜。 代碼不生成網頁,它基本上是一個生成文件的API調用。 我需要能夠在很短的時間內生成盡可能多的這些測試文件,因為我正在進行編碼更改。

代碼就是這樣。 我的工作是能夠對其進行更改,而且目前我甚至無法在沒有巨大開銷的情況下運行它。 在不知道它在做什么的情況下對其進行更改是不負責任的。

部分問題是,當您編寫從Symfony的基本Controller或新的AbstractController擴展的Controller時,它將從容器中加載其他依賴項。 這些服務要么必須在測試中實例化並將它們傳遞給容器,然后在控制器中設置如下:

$loader = new Twig_Loader_Filesystem('/path/to/project/app/Resources/views');
$twig = new Twig_Environment($loader, array(
    'cache' => '/path/to/app/var/cache/templates',
));

# ... other services like routing, doctrine and token_storage

$container = new Container();
$container->set('twig', $twig);

$controller = new MyController();
$controller->setContainer($container);

或者嘲笑它們,這使得你的測試幾乎不可讀,並且在你對代碼所做的每一次改變中都會中斷。

正如您所看到的,這不是一個單元測試,因為您將需要通過調用$this->get()/$this->container->get()或間接調用您從容器中提取的所有服務。通過控制器中的輔助方法,例如getDoctrine()

如果您不以與在生產中使用相同的方式配置服務,這不僅繁瑣,您的測試可能不是很有意義,因為它們可能會通過您的測試但在生產中失敗。

問題的另一部分是您的代碼段內的評論:

這里有200多行程序代碼

沒有看到代碼,我可以告訴你,正確的單元測試這幾乎是不可能的,不值得。

簡短的回答是,你做不到。

我建議使用WebTestCase編寫功能測試使用CodeCeption編寫Selenium,並通過UI間接測試控制器。

一旦您完成了涵蓋操作(主要)功能的測試,您就可以開始重構您的控制器,將事物分成更小的塊和更容易測試的服務。 對於那些新類,單元測試是有意義的。 當您的功能測試為綠色(再次)時,您將知道網站何時再次發生變化。 理想情況下,您不需要更改這些首次測試,因為它們只通過瀏覽器查看您的網站,因此不會受到您所做的任何代碼更改的影響。 請注意不要對模板和路由進行更改。

我發現只需要一些簡短的線就可以將Symfony變成測試工具:

// Load the autoloader class so that the controller can find everything it needs
//$loader = require 'app/vendor/autoload.php';
require 'app/vendor/autoload.php';

// Create a new Symfony kernel instance
$kernel = new \AppKernel('prod', false);
//$kernel = new \AppKernel('dev', true);
// Boot the kernel
$kernel->boot();
// Get the kernel container
$container = $kernel->getContainer();
// Services can be retrieved like so if you need to
//$service = $container->get('name.of.registered.service');

// Create a new instance of your controller
$controller = new \What\You\Call\Your\Bundle\Controller\FooBarController();
// You MUST set the container for it to work properly
$controller->setContainer($container);

在此代碼之后,您可以測試控制器上的任何公共方法。 當然,如果您正在測試生產代碼(因為我必須這樣做;我的開發代碼完全不同,因為代碼庫寫得非常糟糕),請注意您可能正在觸摸數據庫,進行Web調用等。

但是,好處是您可以開始對控制器進行代碼覆蓋,以了解它們無法正常工作的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM