2016-06-30 8 views
0

SF3プロジェクトの作成フォーム(単純な銀行エンティティ用)のテストにはいくつか問題があります。ここでは、テストコード:Symfony 3テスト - フォームテストの "AlreadySubmittedException"

class BankControllerTest extends WebTestCase 
{ 
    /** 
    * Test the creation form action 
    */ 
    function testNewAction() 
    { 
     $client = static::createClient(); 

     // User must be logged in 
     $client->request('GET', '/bank/bank/new'); 
     $response = $client->getResponse(); 
     $this->assertEquals(302, $response->getStatusCode()); 

     // Page request test 
     $client = LoginControllerTest::createClientConnectedTest(); 
     $crawler = $client->request('GET', '/bank/bank/new'); 
     $response = $client->getResponse(); 
     $this->assertEquals(200, $response->getStatusCode()); 

     // Form testing 
     $formData = array(
      'bank[name]' => 'BankTest '.uniqid(), 
      'bank[comment]' => 'Tast bank '.uniqid().' comment.', 
     ); 
     $submitButtonCrawlerNode = $crawler->selectButton('Create'); 
     $form = $submitButtonCrawlerNode->form(); 
     $client->submit($form, $formData); 
     $response = $client->getResponse(); 
     $container = $client->getContainer(); 
     $this->assertEquals(301, $response->getStatusCode()); 
    } 
} 

私に面白いことは、最後の「フォームのテスト」の部分である部分は、私が前にミスを犯した私の場合はすべてのものを貼り付けました。

代わりに "301" httpCode私が欲しいのは、私は500エラーを持っている:

vendor/bin/phpunit src/BillBrother/BankAccountBundle 
[...] 
1) BillBrother\BankAccountBundle\Test\Controller\BankControllerTest::testNewAction 
Failed asserting that 500 matches expected 301. 

    /home/developer/src/BillBrother/BankAccountBundle/Test/Controller/BankControllerTest.php:47 

そして、それは、このエラーを発生させる "AlreadySubmittedException" で見た:

[2016-06-30 08:00:18] request.CRITICAL: Uncaught PHP Exception Symfony\Component\Form\Exception\AlreadySubmittedException: "You cannot add children to a submitted form" at /home/developer/vendor/symfony/symfony/src/Symfony/Component/Form/Form.php line 802 {"exception":"[object] (Symfony\\Component\\Form\\Exception\\AlreadySubmittedException(code: 0): You cannot add children to a submitted form at /home/developer/vendor/symfony/symfony/src/Symfony/Component/Form/Form.php:802)"} [] 

は私がやりました間違った方法で何か?

ご協力いただきありがとうございます。

ここ

私は、このテストで使用されるコードのいくつかの他の部分:

私はcreateClientConnectedTest()静的関数を使用する場所からログインテストファイル、:

/** 
* BillBrother\AuthBundle\Controller test class file. 
* 
* @TODO Write tests 
* @author Neimheadh <[email protected]> 
*/ 
namespace BillBrother\AuthBundle\Tests\Controller; 

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

/** 
* BillBrother\AuthBundle\Controller test class. 
*/ 
class LoginControllerTest extends WebTestCase 
{ 
    /** 
    * Create a connected client. 
    * 
    * @param string $login 
    * @param string $password 
    * @return \Symfony\Bundle\FrameworkBundle\Client 
    */ 
    public static function createClientConnected($login, $password) 
    { 
     return static::createClient(array(), array(
      'PHP_AUTH_USER'  => $login, 
      'PHP_AUTH_PW'  => $password 
     )); 
    } 

    /** 
    * Create a client connected with test account 
    * 
    * @return \Symfony\Bundle\FrameworkBundle\Client 
    */ 
    public static function createClientConnectedTest() 
    { 
     return static::createClientConnected(
      '[email protected]', 
      'password' 
     ); 
    } 

    /** 
    * Test the login form 
    */ 
    public function testLoginform() 
    { 
     $client = static::createClient(); 

     $crawler = $client->request('GET', '/login'); 
    } 

} 

BankTypeクラス:

/** 
* Bank entity type 
* 
* @author Neimheadh <[email protected]> 
*/ 
namespace BillBrother\BankAccountBundle\Form\Type; 

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolver; 

use Symfony\Component\Form\Extension\Core\Type\TextareaType; 

/** 
* Bank type form 
*/ 
class BankType extends AbstractType 
{ 
    /** 
    * Build the form 
    * 
    * @param FormBuilderInterface $builder 
    * @param array $options 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('name') 
      ->add('comment', TextareaType::class) 
     ; 
    } 

    /** 
     * Configure the form default options. 
     * 
     * @param OptionsResolver $resolver 
     */ 
    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'BillBrother\BankAccountBundle\Entity\Bank' 
     )); 
    } 
} 

Bankエンティティクラス:

/** 
* BillBrother bank entity class file. 
* 
* @author Neimheadh <[email protected]> 
*/ 
namespace BillBrother\BankAccountBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use BillBrother\AuthBundle\Entity\User; 
use Datetime; 

/** 
* Bank 
* 
* @ORM\Table(name="bank") 
* @ORM\Entity(repositoryClass="BillBrother\BankAccountBundle\Repository\BankRepository") 
*/ 
class Bank 
{ 
    /** 
    * The bank id. 
    * 
    * @var int 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * Bank creator 
    * 
    * The user account who created the bank. 
    * 
    * If null, it means the bank was created by the system. 
    * 
    * @var User 
    * 
    * @ORM\JoinColumn(name="creator_id", nullable=true) 
    * @ORM\ManyToOne(targetEntity="BillBrother\AuthBundle\Entity\User") 
    */ 
    private $creator; 

    /** 
    * The bank name. 
    * 
    * @var string 
    * 
    * @ORM\Column(name="name", type="string", length=255) 
    */ 
    private $name; 

    /** 
    * Comments about the bank. 
    * 
    * @var string 
    * 
    * @ORM\Column(name="comment", type="text") 
    */ 
    private $comment; 

    /** 
    * Bank row creation date 
    * 
    * @var Datetime 
    * 
    * @ORM\Column(name="create_date", type="datetime") 
    */ 
    private $createDate; 

    /** 
    * Constuctor 
    * 
    * Initialize the creation date to the current date 
    */ 
    public function __construct() 
    { 
     $this->createDate = new Datetime; 
    } 

    /** 
    * Get id 
    * 
    * @return int 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /** 
    * Set name, nullable=tru 
    * @return Bank 
    */ 
    public function setName($name) 
    { 
     $this->name = $name; 

     return $this; 
    } 

    /** 
    * Get name 
    * 
    * @return string 
    */ 
    public function getName() 
    { 
     return $this->name; 
    } 

    /** 
    * Set comment 
    * 
    * @param string $comment 
    * 
    * @return Bank 
    */ 
    public function setComment($comment) 
    { 
     $this->comment = $comment; 

     return $this; 
    } 

    /** 
    * Get comment 
    * 
    * @return string 
    */ 
    public function getComment() 
    { 
     return $this->comment; 
    } 

    /** 
    * Set creator 
    * 
    * @param User $creator 
    * 
    * @return Bank 
    */ 
    public function setCreator(User $creator = null) 
    { 
     $this->creator = $creator; 

     return $this; 
    } 

    /** 
    * Get creator 
    * 
    * @return User 
    */ 
    public function getCreator() 
    { 
     return $this->creator; 
    } 
} 

と呼ばれるコントローラ:私の問題からあった場所、私が見た

✗ bin/console --version 
Symfony version 3.1.1 - app/dev/debug 

✗ vendor/bin/phpunit --version 
PHPUnit 5.4.6 by Sebastian Bergmann and contributors. 


✗ php --version 
PHP 7.0.6 (cli) (built: May 24 2016 03:29:56) (NTS) 
Copyright (c) 1997-2016 The PHP Group 
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies 

答えて

0

/** 
* BillBrother bank account bundle bank controller class file. 
* 
* @author Neimheadh <[email protected]> 
*/ 
namespace BillBrother\BankAccountBundle\Controller; 

use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 
use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\Form\Extension\Core\Type\SubmitType; 

use BillBrother\BankAccountBundle\Entity\Bank; 
use BillBrother\BankAccountBundle\Form\Type\BankType; 

/** 
* BillBrother application bank account bank controller. 
*/ 
class BankController extends Controller 
{ 
    /** 
    */ 
    private function _buildForm(Request $request, Bank $bank) 
    { 
     $form = $this->createForm(BankType::class, $bank); 
     $form->handleRequest($request); 

     if($form->isValid()) { 
      $em = $this->getDoctrine()->getEntityManager(); 
      $em->persist($bank); 
      $em->flush(); 
     } 

     $form->add('submit', SubmitType::class, array(
      'label' => 'Create' 
     )); 
     return $form; 
    } 

    /** 
    * Bank account bundle bank list page action. 
    * 
    * @Route("/banks", name="billbrother_bankaccount_bank_list") 
    */ 
    public function listAction() 
    { 
     return $this->render('BillBrotherBankAccountBundle:Bank:list.html.twig'); 
    } 

    /** 
    * Create a new bank page action. 
    * 
    * @param Request $request 
    * 
    * @Route("/bank/new", name="billbrother_bankaccount_bank_new") 
    */ 
    public function newAction(Request $request) 
    { 
     $bank = new Bank(); 
     $form = $this->_buildForm($request, $bank); 

     if($form->isValid()) 
      return $this->redirectToRoute(
       'billbrother_bankaccount_bank_edit', 
       array('id'=>$bank->getId()) 
      ); 

     return $this->render(
      'BillBrotherBankAccountBundle:Bank:form.html.twig', 
      array(
       'form' => $form->createView() 
      ) 
     ); 
    } 

    /** 
    * Modify a bank page action. 
    * 
    * @Route("/bank/edit/{id}", name="billbrother_bankaccount_bank_edit") 
    */ 
    public function editAction($id) 
    { 
     return $this->render('BillBrotherBankAccountBundle:Bank:form.html.twig'); 
    } 
} 

とバージョンについて。私のコントローラでは:

private function _buildForm(Request $request, Bank $bank) 
{ 
    $form = $this->createForm(BankType::class, $bank); 
    $form->handleRequest($request); 

    if($form->isValid()) { 
     $em = $this->getDoctrine()->getEntityManager(); 
     $em->persist($bank); 
     $em->flush(); 
    } 

    $form->add('submit', SubmitType::class, array(
     'label' => 'Create' 
    )); 
    return $form; 
} 

私たちは、私は、フォームhandleRequest()後に私の「送信」ボタンを追加してください。コードを移動することにより:

$form->add('submit', SubmitType::class, array(
     'label' => 'Create' 
    )); 

ちょうど私のフォームを作成した後、すべてがOKです。

最終的な機能コード:

private function _buildForm(Request $request, Bank $bank) 
{ 
    $form = $this->createForm(BankType::class, $bank); 
    $form->add('submit', SubmitType::class, array(
     'label' => 'Create' 
    )); 
    $form->handleRequest($request); 

    if($form->isValid()) { 
     $em = $this->getDoctrine()->getEntityManager(); 
     $em->persist($bank); 
     $em->flush(); 
    } 

    return $form; 
}