2010-12-06 3 views
37

Я попытался найти что-то об этом в Google, но ничего не получилось. У меня есть класс TestCase, который наследуется от WebTestCase, с некоторыми методами, которые я хочу использовать во всех своих подразделений/функциональных тестов:Symfony 2 + Doctrine 2 + PHPUnit 3.5: Сериализация исключения закрытия

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

Затем мой блок тест:

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

она работает, прежде чем , но, вдруг, после того как я обновил свои поставщики (учение включено), он начал бросать это исключение:

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 

Я обнаружил, что проблема исходит от загрузки прибора. Если я удалю код, который загружает светильники, он работает.

Кто-нибудь знает, что может быть неправильным в моем коде? Это лучший способ загрузки светильников?

Спасибо!

ответ

86

Технически не связано с вашей проблемой. Тем не менее, мне очень трудно было попытаться решить проблему «Сериализация« Закрытие »не допускается при использовании PHPUnit, и этот вопрос является лучшим результатом Google.

Проблема возникает из-за того, что PHPUnit сериализует все $ GLOBALS в системе, чтобы обеспечить их резервное копирование во время тестирования. Затем он восстанавливает их после завершения теста.

Однако, если у вас есть закрытие в вашем GLOBAL пространстве, это вызовет проблемы. Существует два способа решить эту проблему.

Вы можете полностью отключить глобальную процедуру резервного копирования, используя аннотацию.

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

Или, если вы знаете, какая переменная является причиной проблемы (обратите внимание на лямбда в var_dump ($ GLOBALS)), вы можете просто черный список переменной (ы) проблемы.

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

Спасибо за ваш ответ! это действительно то, что я должен был сделать, чтобы решить большинство моих проблем с этим исключением. Единственная проблема, которую я получил, по-видимому, исходила из компонента Validator Symfony 2 в моих тестах. К сожалению, я не мог понять, почему это происходит. – Adrian 2011-02-28 14:34:36

4

Вы также можете попробовать.

<phpunit backupGlobals="false"> 
    <testsuites> 
     <testsuite name="Test"> 
      <directory>.</directory> 
     </testsuite> 
    </testsuites> 
</phpunit> 
Смежные вопросы