2013-05-10 58 views
0

編輯Symfony的2 SessionCsrfProvider&PHPUnit的測試

其實這個回答我,是如此簡單:

$session = $this->getMock(
    '\Symfony\Component\HttpFoundation\Session\Session', 
    array(), 
    array(), 
    '', 
    false // don't call constructor 
); 
$container->register('session', $session); 

嘲諷PHPUnit的引導文件中的會話對象。

++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++

在我看來,這是不可能的,正確地測試。

我正在使用Symfony 2獨立組件 - 不使用FrameworkBundle等等。我有一個控制器,它反過來創建一個窗體,然後(嘗試)將Csrf擴展添加到窗體構建器。

然而,傳遞一個會話對象只是給我:

RuntimeException: Failed to start the session because headers have already been sent. 

一些代碼產生這樣的:

$session = $this->container->get('session') // instance of Symfony\Component\HttpFoundation\Session\Session 
$form_obj = new MyForm(); // extends AbstractType 
$secret = $form_obj->getName(); // something random 
$form_obj->addExtension(new CsrfExtension(new SessionCsrfProvider($session, $secret))); 

OK,所以會無法啓動,因爲PHPUnit的首先發送輸出。把 session_start();

位於引導文件的頂部不起作用或不起作用。

RuntimeException: Failed to start the session because a session has already been started 

無論如何,這是一個軟肋修復,因爲無論如何您都不會在2個不同的地方開始會話。

所以接下來,我想註冊一個模擬會話對象按照下列指示:http://symfony.com/doc/master/components/http_foundation/session_testing.html

但很遺憾的SessionCsrfProvider接口要求:

Argument 1 passed to 
Symfony\Component\Form\Extension\Csrf\CsrfProvider\SessionCsrfProvider::__construct() 
must be an instance of Symfony\Component\HttpFoundation\Session\Session, 
instance of 
Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorage given 

所以......我不能實際使用SessionCsrfProvider在任何測試代碼中,除非我將會話作爲PHPUnit模擬提供給它...但是那樣會要求我改變代碼的設計,將會話對象注入構造函數或參數中,作爲某種方法調用addExtension( ) 方法。目前,上面添加擴展的代碼片段被封裝在一個函數本身中,所以這意味着需要手動傳入一個會話對象,我真的不想介紹它。

有什麼想法?

回答

0

我知道我對此有點晚了,但另一種更好的方法是使用Symfonys MockArraySessionStorage。

$session = new Session(new MockArraySessionStorage()); 

$csrfProvider = new SessionCsrfProvider($session, $secret);