Symfony 2 + Doctrine 2 + PHPUnit 3.5:closuresexception的序列化
我试图在Google上find这方面的信息,但没有发现。 我有一个从WebTestCaseinheritance的TestCase类,在我所有的单元/函数testing中都使用了一些方法:
<?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 ); } }
那么,我的unit testing:
<?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
我发现问题来自夹具加载。 如果我删除加载装置的代码,它的工作原理。
有谁知道我的代码可能是错的? 这是加载夹具的最佳方式?
谢谢!
技术上与您的问题没有关系。 然而,在使用PHPUnit的时候,我很难试图解决“封闭的序列化”问题,而这个问题是Google的最高结果。
问题来自PHPUnit将系统中的所有$ GLOBALS序列化为在testing运行时对其进行基本备份的事实。 然后在testing完成后恢复它们。
但是,如果您在GLOBAL空间中有任何closures,将会导致问题。 有两种方法来解决它。
您可以使用注释完全禁用全局备份过程。
/** * @backupGlobals disabled */ class MyTest extends PHPUnit_Framework_TestCase { // ... }
或者,如果您知道哪个variables导致问题(在var_dump($ GLOBALS)中查找lambda),则可以将问题variables列入黑名单。
class MyTest extends PHPUnit_Framework_TestCase { protected $backupGlobalsBlacklist = array('application'); // ... }
你也可以试试。
<phpunit backupGlobals="false"> <testsuites> <testsuite name="Test"> <directory>.</directory> </testsuite> </testsuites> </phpunit>