4

我正在使用Liip functional test bundle在Symfony中創建功能測試。Symfony2功能測試無法到達字段「_token」

我目前堅持提交表單。
我想添加一個新的'日誌'使用功能測試。

如果我嘗試添加一個新的日誌低谷,我得到以下請求參數的UI:

'WorkLog' => array(
    'submit' => '', 
    'hours' => '8', 
    'minutes' => '0', 
    'note' => 'some text', 
    '_token' => '4l5oPcdCRzxDKKlJt_RG-B1342X52o0C187ZLLVWre4' 
); 

但是當測試提交表單,我得到了相同的參數,但沒有令牌

'WorkLog' => array(
    'submit' => '', 
    'hours' => '8', 
    'minutes' => '0', 
    'note' => 'some text' 
); 

我想我可以通過添加「_token」字段的形式要求解決問題,但是當我然後跑再次測試它給了我一個錯誤:

InvalidArgumentException: Unreachable field "_token"

功能測試的代碼:

namespace App\AdminBundle\Tests\Controller; 

use Liip\FunctionalTestBundle\Test\WebTestCase; 

use Symfony\Bundle\FrameworkBundle\Client; 
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; 
use Symfony\Component\BrowserKit\Cookie; 

class LogControllerTest extends WebTestCase 
{ 
    private $client; 
    private $em; 
    private $fixtures; 

    public function setUp() 
    { 
     $this->client = static::makeClient(); 
     $this->em = $this->client->getContainer()->get('doctrine')->getManager(); 

     $this->fixtures = $this->loadFixtures(array(
      'App\AdminBundle\DataFixtures\ORM\LoadUserData', 
      'App\AdminBundle\DataFixtures\ORM\LoadSubscriptionTypesData', 
      'App\AdminBundle\DataFixtures\ORM\LoadSubscriptionData', 
      'App\AdminBundle\DataFixtures\ORM\LoadWorkLogData', 
     ))->getReferenceRepository(); 
    } 

    public function testAddNewLog() 
    { 
     $accountId = $this->fixtures->getReference('userAccount')->getId(); 

     // log in with admin account 
     $this->logIn('adminAccount'); 

     $crawler = $this->client->request('GET', '/admin/worklog/account/'.$accountId.'/add'); 
     $csrfToken = $this->client->getContainer()->get('form.csrf_provider')->generateCsrfToken('post_type'); 

     $form = $crawler->selectButton('WorkLog_submit')->form(array(
      'WorkLog' => array(
       'hours' => '8', 
       'minutes' => '0', 
       'note' => 'some text', 
       '_token' => $csrfToken 
      ), 
     ), 'POST'); 

     $crawler = $this->client->submit($form); 
    } 
} 

我的問題:我怎樣才能提交表單與令牌?

回答

3

我不與LIIP功能測試包的工作,但我通常用的形式和_token以下方式工作:

$crawler = $this->client->request('GET', $url); 

    // retrieves the form token 
    $token = $crawler->filter('[name="select_customer[_token]"]')->attr("value"); 

    // makes the POST request 
    $crawler = $this->client->request('POST', $url, array(
     'select_customer' => array(
      '_token' => $token, 
      'customerId' => $customerId, 
     ), 
    )); 

希望這有助於。

+1

我實際上試圖讓測試處理的形式相同的方式,用戶會這樣做。這就是爲什麼我嘗試用爬蟲提交表單。如果我不能很快弄清楚,我會嘗試你的解決方案。 – Szenis

+0

@Szenis:我遇到了同樣的問題,您是否找到解決方案,或者您是否使用Matteo解決方案? –

+0

@AlexandreT我確實使用了Matteo提供的解決方案 – Szenis

0

我遇到了幾個小時的非常類似的問題... 我的方法有點不同。當我詢問一些幫助時,Stackoverflow發現了一個可能的重複,並且我發現了你的問題。你的問題可以幫助我回答類似的問題。

你這樣做:

$form = $crawler->selectButton('WorkLog_submit')->form(array(
     'WorkLog' => array(
      'hours' => '8', 
      'minutes' => '0', 
      'note' => 'some text', 
      '_token' => $csrfToken 
     ), 
    ), 'POST'); 

你試圖做一步到位。但這是不可能的,因爲Liip函數包試圖用一些神奇的方法設置數組的數組,並且它崩潰。我明白,我們有更多的步驟來做到這一點:

我用它在我的代碼一樣,(你可以看到,我沒有更多的使用LIIP束):

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; 
class GameControllerTest extends WebTestCase 
{ 
    public function testLoadGame(){ 


     $client = static::createClient(); 
     $crawler = $client->request('GET', '/loadGame'); 
     $form = $crawler->selectButton('Load')->form(); 
     $field = $form->get("load[uuid]"); 
     $field->setValue($uuid1[0]); 
     $form->set($field); 
     $client->submit($form); 
     $response = $client->getResponse(); 
     self::assertTrue($response->isRedirect('/game')); 

    } 
} 

所以我認爲,解決你的問題是:

$form = $crawler->selectButton('WorkLog_submit')->form();   
    //dump($form) //uncomment this line to have a look on the array of array 
    $fieldToken = $form->get("WorkLog[_token]"); 
    $fieldToken->setValue($csrfToken); 
    $form->set($fieldToken); 
    $client->submit($form);