2010-12-06 18 views
37

Bu konuda Google'da bir şey bulmaya çalıştım ancak hiçbir şey çıkmadı.Symfony 2 + Doctrine 2 + PHPUnit 3.5: Kapanış istisnasının serileştirilmesi

<?php 

namespace Application\FaxServerBundle\Test; 

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; 
use Doctrine\Common\DataFixtures\Loader; 
use Doctrine\Common\DataFixtures\Executor\ORMExecutor; 
use Doctrine\Common\DataFixtures\Purger\ORMPurger; 

use Application\FaxServerBundle\DataFixtures\ORM\NetworkConfigurationData; 

class TestCase extends WebTestCase 
{ 
    protected $kernel; 

    public function setUp() 
    { 
     parent::setUp(); 
    } 

    public function getEm() 
    { 
     return $this->getService('doctrine.orm.entity_manager'); 
    } 

    public function getNetworkConfigurationRepository() 
    { 
     return $this->getEm()->getRepository('Application\FaxServerBundle\Entity\NetworkConfiguration'); 
    } 

    public function loadNetworkConfigurationFixtures() 
    { 
     $loader = new Loader(); 
     $loader->addFixture(new NetworkConfigurationData()); 

     $this->loadFixtures($loader); 
    } 

    public function loadFixtures($loader) 
    { 
     $purger  = new ORMPurger(); 
     $executor = new ORMExecutor($this->getEm(), $purger); 
     $executor->execute($loader->getFixtures()); 
    } 

    protected function getService($name, $kernel = null) 
    { 
     return $this->getBootedKernel()->getContainer()->get($name); 
    } 

    protected function hasService($name, $kernel = null) 
    { 

     return $this->getBootedKernel()->getContainer()->has($name); 
    } 

    protected function getBootedKernel() 
    { 
     $this->kernel = $this->createKernel(); 

     if (!$this->kernel->isBooted()) 
     { 
      $this->kernel->boot(); 
     } 

     return $this->kernel; 
    } 

    public function generateUrl($client, $route, $parameters = array()) 
    { 
     return $client->getContainer()->get('router')->generate($route, $parameters); 
    } 
} 

Sonra benim birim test:

<?php 

namespace Application\FaxServerBundle\Tests\Entity; 

use Doctrine\ORM\AbstractQuery; 

use Application\FaxServerBundle\Entity; 
use Application\FaxServerBundle\Test\TestCase; 

class NetworkConfigurationRepositoryTest extends TestCase 
{ 
public function setUp() 
{ 
    parent::setUp(); 

    $this->loadNetworkConfigurationFixtures(); 
} 

public function testGetConfiguration() 
{ 
    $config = $this->getNetworkConfigurationRepository()->getConfigurationArray(); 

    $this->assertInternalType('array', $config); 
    $this->assertEquals(6, count($config)); 
    $this->assertArrayHasKey('id', $config); 
    $this->assertArrayHasKey('ip', $config); 
    $this->assertArrayHasKey('gateway', $config); 
    $this->assertArrayHasKey('subnetMask', $config); 
    $this->assertArrayHasKey('primaryDns', $config); 
    $this->assertArrayHasKey('secondaryDns', $config); 
} 

public function testGetConfigurationObject() 
{ 
    $config = $this->getNetworkConfigurationRepository()->getConfigurationObject(); 

    $this->assertInternalType('object', $config); 
} 

public function testGetConfigurationArray() 
{ 
    $config = $this->getNetworkConfigurationRepository()->getConfigurationArray(); 

    $this->assertInternalType('array', $config); 
} 
} 

önce It çalışıyordu ben ben bütün birim/fonksiyonel testlerde kullanmak isteyen bazı yöntemlerle, WebTestCase devraldığı bir dizge sınıf var sorun fikstürü yükleme geldiğini tespit ettik

3) Application\FaxServerBundle\Tests\Entity\NetworkConfigurationRepositoryTest::testGetConfigurationArray 
RuntimeException: PHP Fatal error: Uncaught exception 'PDOException' with message 'You cannot serialize or unserialize PDO instances' in -:32 
Stack trace: 
#0 [internal function]: PDO->__sleep() 
#1 -(32): serialize(Array) 
#2 -(113): __phpunit_run_isolated_test() 
#3 {main} 

Next exception 'Exception' with message 'Serialization of 'Closure' is not allowed' in -:0 
Stack trace: 
#0 -(0): serialize() 
#1 -(113): __phpunit_run_isolated_test() 
#2 {main} 
    thrown in - on line 0 

: Ben satıcıları (doktrin dahil) güncellendi sonra ama, aniden, bu istisna başladı. Armatürleri yükleyen kodu kaldırırsam çalışır.

Kodumda neyin yanlış olabileceğini bilen var mı? Bu, fikstür yüklemenin en iyi yolu mu?

Teşekkürler!

cevap

86

Sorununuz ile teknik olarak ilgili değil. Ancak, PHPUnit kullanırken "Kapanış 'serileşmesine izin verilmez" sorunu çözmeye çalışırken gerçekten çok zor bir zaman geçirdim ve bu soru en üstteki Google sonucudur.

Sorun, PHPUnit'in sistem çalışırken tüm GLOBALS'i seri hale getirmesi ve test çalışması sırasında bunları yedeklemesini sağlamaktır. Daha sonra test bittikten sonra bunları geri yükler. Ancak, GLOBAL alanınızda herhangi bir kapatma varsa, sorunlara neden olacaktır. Çözmenin iki yolu var.

Genel yedekleme prosedürünü tamamen bir ek açıklama kullanarak devre dışı bırakabilirsiniz. Soruna neden olan değişken biliyorsanız

/** 
* @backupGlobals disabled 
*/ 
class MyTest extends PHPUnit_Framework_TestCase 
{ 
    // ... 
} 

Veya (var_dump ($ GLOBALS) bir lambda arayın), sorunun değişken (ler) kara listeye sadece edebilirsiniz.

+1

Cevabınız için teşekkürler! Bu gerçekten benim problemlerimin çoğunu bu istisna ile çözmek için yapmak zorunda olduğum şey. Gördüğüm tek sorun benim testlerimde Symfony 2'nin Validator bileşeninden geldi. Ne yazık ki, bunun neden olduğunu anlayamadım. – Adrian

+0

Bu, kendi başıma çalışmak için çok acı çekerdi. Faydalı cevap için +1 – Rowan

+1

Bu PHPUnit 3.6'da giderilmiş gibi görünüyor: https://github.com/sebastianbergmann/phpunit/pull/352 – scribu

4

Ayrıca, deneyebilirsiniz.

<phpunit backupGlobals="false"> 
    <testsuites> 
     <testsuite name="Test"> 
      <directory>.</directory> 
     </testsuite> 
    </testsuites> 
</phpunit>