2012-12-03 8 views
5

सत्रों को लागू करने वाले नियंत्रक विधि पर नियंत्रक आधारित इकाई परीक्षण चलाने की कोशिश करते समय मैं किसी समस्या में भाग रहा हूं।PHPUnit Symfony2 सत्रों में विफल रहा

/** 
* @Route("/api/logout") 
*/ 
public function logoutAction() 
{ 
    $session = new Session(); 
    $session->clear(); 

    return $this->render('PassportApiBundle:Login:logout.html.twig'); 
} 

और कार्यात्मक परीक्षण:

public function testLogout() 
{ 
    $client = static::createClient(); 
    $crawler = $client->request('GET', '/api/logout'); 
    $this->assertTrue($client->getResponse()->isSuccessful()); 
} 

त्रुटि है कि उत्पादन किया जाता है:

Failed to start the session because headers have already been sent. (500 Internal Server Error)

मैं कोशिश की है

इस मामले में, यहाँ नियंत्रक विधि है परीक्षण में $this->app['session.test'] = true; में रखकर, लेकिन अभी भी नहीं जाना है। क्या किसी ने इस तरह के किसी मुद्दे को हल करने का प्रयास किया है जो एक सत्र का उपयोग करने वाले नियंत्रक को यूनिट परीक्षण कर रहा है?

+1

यदि आप 'सत्र' वर्ग (https://github.com/symfony/symfony/blob/2.1/src/Symfony/Component/HttpFoundation/Tests/Session/SessionTest.php) के लिए परीक्षण देखते हैं, तो यह ऐसा लगता है कि सत्र शुरू करने से बचने के लिए आपको 'MockArraySessionStorage' का एक उदाहरण इंजेक्ट करना चाहिए। – Sven

+0

मैंने उन पंक्तियों को सेट अप किया है, हालांकि, मैं इसे '$ क्लाइंट = स्थिर :: createClient();' में कैसे पास करूं? अकेले उन पंक्तियों को जोड़ना एक ही त्रुटि के परिणामस्वरूप होता है। –

+0

हां, समस्या यह है कि आपका नियंत्रक कुछ भी इंजेक्ट करने की पेशकश नहीं करता है। 'नए' ऑपरेशन में कोई पैरामीटर नहीं है, और किसी भी तरह से परीक्षण से कुछ भी पास करने का कोई तरीका नहीं होगा। लेकिन मुझे लगता है कि सिम्फनी 2 इसके लिए डीआई ढांचे को प्रयोग करने में सक्षम होना चाहिए। क्या आपने इसे उदाहरण के लिए पढ़ा है: http://stackoverflow.com/questions/10106195/symfony-2- निर्भरता- इंजेक्शन-di-of-controllers इसके अतिरिक्त, सिम्फनी दस्तावेज़ इस तरह के सत्र में आने का सुझाव देते हैं: '$ session = $ यह-> getRequest() -> getSession(); '- यह PHPUnit बूटस्ट्रैपिंग को मॉक सत्र ऑब्जेक्ट्स – Sven

उत्तर

12

सबसे पहले आपको कंटेनर से सत्र ऑब्जेक्ट का उपयोग करना चाहिए। तो अपनी कार्रवाई और अधिक की तरह दिखना चाहिए:

/** 
* @Route("/api/logout") 
*/ 
public function logoutAction() 
{ 
    $session = $this->get('session'); 
    $session->clear(); 

    return $this->render('PassportApiBundle:Login:logout.html.twig'); 
} 

और फिर अपने परीक्षण में आप "ग्राहक के कंटेनर" में सेवा इंजेक्षन कर सकते हैं। तो:

public function testLogout() 
{ 
    $sessionMock = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session') 
     ->setMethods(array('clear')) 
     ->disableOriginalConstructor() 
     ->getMock(); 

    // example assertion: 
    $sessionMock->expects($this->once()) 
     ->method('clear'); 

    $client = static::createClient(); 
    $container = $client->getContainer(); 
    $container->set('session', $sessionMock); 

    $crawler = $client->request('GET', '/api/logout'); 
    $this->assertTrue($client->getResponse()->isSuccessful()); 
} 

इस कोड के साथ आप अपनी सत्र सेवा के साथ जो कुछ भी चाहते हैं वह कर सकते हैं। लेकिन आपको दो चीजों से अवगत होना चाहिए:

  • यह नकली केवल एक अनुरोध के लिए सेट की जाएगी (यदि आप इसे अगले में उपयोग करना चाहते हैं, तो आपको इसे फिर से स्थापित करना चाहिए)। ऐसा इसलिए है क्योंकि क्लाइंट कर्नेल को पुनरारंभ करता है और प्रत्येक अनुरोध के बीच कंटेनर पुनर्निर्माण करता है।
  • सत्र Symfony 2.1 में से निपटने Symfony 2 से थोड़ा अलग है

संपादित करें:

मैं साइप्रायन की प्रतिक्रिया को पूरा करने का दावा

+1

धन्यवाद का उपयोग करने में सक्षम कर सकता है। '$ Session = $ this-> को प्राप्त करें ('सत्र') 'इसे पूरी तरह से काम करता है। मुझे नहीं पता कि दस्तावेज़ों ने मुझे 'नया सत्र() 'का उपयोग करने के लिए क्यों कहा ... http://symfony.com/doc/master/components/http_foundation/sessions.html –

1

जोड़ दिया है यहाँ।

स्वेन बताते हैं और जब, सिम्फोनी के डॉक http://symfony.com/doc/2.3/components/http_foundation/session_testing.html को देख आप पहली बार निर्माता तर्क के रूप में एक MockFileSessionStorage वस्तु के साथ नकली सत्र instanciate करने के लिए है के रूप में।

आप उपयोग करने की आवश्यकता:

use Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorage; 

और कोड होना चाहिए:

$sessionMock = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\Session') 
     ->setMethods(array('clear')) 
     ->disableOriginalConstructor() 
     ->setConstructorArgs(array(new MockFileSessionStorage())) 
     ->getMock(); 
+0

एक बेहतर तरीका esp के साथ हो सकता है Symfony2 का नया संस्करण लेकिन मुझे अभी भी यह पता लगाने की आवश्यकता है कि कैसे - https://coderwall.com/p/newa2q/testing-with-sessions-symfony2 – Christian

6

मेरे मामले में, यह config_test.yml में

framework: 
    session: 
     storage_id: session.storage.mock_file 

स्थापित करने के लिए पर्याप्त था। वाईएमएमवी, और मेरे पास इतना विचार नहीं है कि मैं वास्तव में क्या कर रहा हूं, लेकिन यह मेरे लिए काम करता है।

+0

मेरे पास पहले से ही 'config_test.yml' में सेटिंग है, लेकिन मुझे मिल गया है 'घातक त्रुटि: किसी सदस्य फ़ंक्शन को कॉल करें() '$ सत्र-> प्राप्त करें (' ... ') पर एक गैर-ऑब्जेक्ट पर प्राप्त करें;' जहां '$ session'' $ session = $ से है- > container-> मिलता है ('अनुरोध') -> getSession(); ' – Sithu