2010-12-06 4 views
37

Ich habe versucht, etwas über Google herauszufinden, aber nichts kam heraus. Ich habe eine Testcase-Klasse, die von WebTestCase, mit einigen Methoden erbt, die ich in meinem ganzen Einheit/Funktionstests verwenden mag:Symfony 2 + Doctrine 2 + PHPUnit 3.5: Serialisierung der Closure-Ausnahme

<?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); 
    } 
} 

Dann mein Unit-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); 
} 
} 

Es funktioniert vor , aber plötzlich, nachdem ich meinen Anbieter aktualisiert (Lehre enthalten), begann es, diese Ausnahme zu werfen:

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 

ich, dass das Problem aus der Halterung Laden kommt gefunden habe. Wenn ich den Code lösche, der Fixtures lädt, funktioniert es.

Weiß jemand, was in meinem Code falsch sein könnte? Ist das der beste Weg, um Leuchten zu laden?

Danke!

Antwort

86

Nicht technisch mit Ihrem Problem verbunden. Allerdings hatte ich wirklich Schwierigkeiten, das Problem der "Serialisierung von 'Schließen' ist nicht erlaubt" bei der Verwendung von PHPUnit zu lösen, und diese Frage ist das beste Google-Ergebnis.

Das Problem kommt von der Tatsache, dass PHPUnit alle $ GLOBALS im System serialisiert, um sie während des Tests zu sichern. Es stellt sie dann wieder her, nachdem der Test abgeschlossen ist.

Wenn Sie jedoch Schließungen in Ihrem GLOBAL Bereich haben, wird es Probleme verursachen. Es gibt zwei Möglichkeiten, es zu lösen.

Sie können die globale Sicherungsprozedur vollständig deaktivieren, indem Sie eine Anmerkung verwenden.

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

Oder, wenn Sie wissen, welche Variable das Problem verursacht (suchen Sie nach einem Lambda in var_dump ($ GLOBALS)), können Sie die schwarze Liste nur das Problem Variable (n).

class MyTest extends PHPUnit_Framework_TestCase 
{ 
    protected $backupGlobalsBlacklist = array('application'); 
    // ... 
} 
+1

Danke für Ihre Antwort! Das war tatsächlich das, was ich tun musste, um die meisten meiner Probleme mit dieser Ausnahme zu lösen. Das einzige Problem, das ich habe, kam offensichtlich von der Validator-Komponente von Symfony 2 in meinen Tests. Leider konnte ich nicht herausfinden, warum es so weit ist. – Adrian

+0

Das wäre mir so schwer gefallen. +1 für nützliche Antwort – Rowan

+1

Dies scheint in PHPUnit 3.6 behoben worden zu sein: https://github.com/sebastianbergmann/phpunit/pull/352 – scribu

4

Sie können es auch versuchen.

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