У меня был небольшой тест сделано в PHP для контроллера я написал в Symfony2:PHPUnit: Тестирование формы представления с сессионных переменных, хранящихся в Symfony2
class DepositControllerTest extends WebTestCase {
public function testDepositSucceeds() {
$this->crawler = self::$client->request(
'POST',
'/deposit',
array("amount" => 23),
array(),
array()
);
$this->assertEquals(
"Deposit Confirmation",
$this->crawler->filter("title")->text());
}
}
До здесь, все было здорово. Проблема началась, когда я понял, что хочу отключить возможные повторные представления при обновлении страницы. Поэтому я добавил небольшой механизм для отправки nonce при каждом представлении.
Он работает что-то вроде этого:
class ReplayManager {
public function getNonce() {
$uid = $this->getRandomUID();
$this->session->set("nonce", $uid);
return $uid;
}
public function checkNonce($cnonce) {
$nonce = $this->session->get("nonce");
if ($cnonce !== $nonce)
return false;
$this->session->set("nonce", null);
return true;
}
}
Так что я должен был mofidy контроллер, чтобы получить временное значение при отображении формы, и потребляют его при подаче.
Но теперь это представляет проблему. Я не могу сделать запрос к POST /deposit
, потому что я не знаю, что отправить nonce. Я подумал просить сначала GET /deposit
визуализировать форму и установить ее для использования в POST
, но я подозреваю, что сеансы Symfony2 не работают в PHPUnit.
Как я могу решить эту проблему? Я бы не захотел пойти на тесты Selenium, так как они значительно медленнее, не говоря уже о том, что мне пришлось бы переписать много тестов.
UPDATE: Я добавляю очень упрощенную версию кода контроллера по запросу.
class DepositController extends Controller{
public function formAction(Request $request){
$this->replayManager = $this->getReplayManager();
$context["nonce"] = $this->replayManager->getNonce();
return $this->renderTemplate("form.twig", $context);
}
protected function depositAction(){
$this->replayManager = $this->getReplayManager();
$nonce = $_POST["nonce"];
if (!$this->replayManager->checkNonce($nonce))
return $this->renderErrorTemplate("Nonce expired!");
deposit($_POST["amount"]);
return $this->renderTemplate('confirmation.twig');
}
protected function getSession() {
$session = $this->get('session');
$session->start();
return $session;
}
protected function getReplayManager() {
return new ReplayManager($this->getSession());
}
}
Не могли бы вы показать свой код контроллера? Что еще делает ReplayManager? Я думаю, что ваша проблема здесь заключается в разделении проблем, и ваш код контроллера может быть полезен для подтверждения этого. – vascowhite
Done, я написал очень упрощенную версию контроллера –
Почему бы не использовать [PRG pattern] (http://en.wikipedia.org/wiki/Post/Redirect/Get)? – sectus