Функциональный тест Symfony2 Недоступное поле & quot; _token & quot;

Я создаю функциональный тест в Symfony, используя Liip функциональный тестовый комплект.

В настоящее время я застрял при отправке формы.
Я пытаюсь добавить новый «журнал» с помощью функционального теста.

Если я пытаюсь добавить новый журнал через пользовательский интерфейс, я получаю следующие параметры запроса:

'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: недостижимое поле «_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);
}
}

Мой вопрос: Как я могу отправить форму с токеном?

4

Решение

Я не работаю с Liip Functional Test Bundle, но я обычно работаю с формой и _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,
),
));

Надеюсь это поможет.

3

Другие решения

Я столкнулся с очень похожей проблемой в течение нескольких часов …
Мой метод был немного другим. Когда я просил помощи, 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);
0

По вопросам рекламы [email protected]