2010-12-06 37 views
37

我试图在Google上找到关于此的一些信息,但没有任何结果。我有一个从WebTestCase继承,有一些方法,我想在我所有的单元/功能测试使用一个TestCase类: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时,我很难试图解决“封闭的序列化”问题,而这个问题是谷歌的最高结果。

问题出在PHPUnit将系统中的所有$ GLOBALS序列化为在测试运行时重要备份它们的事实。然后在测试完成后恢复它们。

但是,如果您在GLOBAL空间中有任何关闭,将会导致问题。有两种方法可以解决它。

您可以使用注释完全禁用全局备份过程。

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

或者,如果你知道哪个变量引起的问题(找一个lambda中的var_dump($ GLOBALS)),你可以黑名单问题变量(一个或多个)。

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

感谢您的回答!这确实是我必须做的,以解决这个例外中的大部分问题。我的测试中唯一出现的问题显然来自Symfony 2的Validator组件。可悲的是,我无法弄清楚它为什么会发生。 – Adrian 2011-02-28 14:34:36

4

您也可以试试。

<phpunit backupGlobals="false"> 
    <testsuites> 
     <testsuite name="Test"> 
      <directory>.</directory> 
     </testsuite> 
    </testsuites> 
</phpunit> 
相关问题