Skip to content

Instantly share code, notes, and snippets.

@maryo
Last active August 29, 2015 14:03
Show Gist options
  • Save maryo/34ca7852e8031e4c9f66 to your computer and use it in GitHub Desktop.
Save maryo/34ca7852e8031e4c9f66 to your computer and use it in GitHub Desktop.
Doctrine2 isolation of tests
<?php
namespace Company\SecretBundle\Test;
use Doctrine\DBAL\Connection;
use Symfony\Bundle\FrameworkBundle\Client as BaseClient;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\HttpKernel\TerminableInterface;
/**
* @property KernelInterface $kernel
* @property Response $response
*/
class Client extends BaseClient
{
/** @var bool */
private $requested = false;
/**
* @param string $method
* @param string $uri
* @param array $parameters
* @param File[] $files
* @param array $server
* @param string|null $content
* @param bool $changeHistory
* @return Response
*/
public function request(
$method,
$uri,
array $parameters = array(),
array $files = array(),
array $server = array(),
$content = null,
$changeHistory = true
) {
parent::request($method, $uri, $parameters, $files, $server, $content, $changeHistory);
return $this->response;
}
/**
* {@inheritDoc}
*/
protected function doRequest($request)
{
/* @var $connection Connection */
$connection = $this->getContainer()->get('doctrine.dbal.default_connection');
if ($this->requested) {
$this->kernel->shutdown();
$this->kernel->boot();
}
$this->setConnection($connection);
$this->requested = true;
$response = $this->kernel->handle($request);
if ($this->kernel instanceof TerminableInterface) {
$this->kernel->terminate($request, $response);
}
return $response;
}
/**
* @link http://alexandre-salome.fr/blog/Symfony2-Isolation-Of-Tests
* @param Connection $connection
*/
private function setConnection(Connection $connection)
{
$container = $this->getContainer();
$eventManager = $connection->getEventManager();
$oldListeners = $eventManager->getListeners();
$newListeners = $container
->get('doctrine.dbal.default_connection')
->getEventManager()
->getListeners()
;
// The connection instance contains also the event manager instance.
// So replacing the connection means that all listeners are also replaced
// thus it's needed to replace the old listeners with the listeners registered in the new container.
foreach ($oldListeners as $event => $listeners) {
foreach ($listeners as $listener) {
$eventManager->removeEventListener($event, $listener);
}
}
foreach ($newListeners as $event => $listeners) {
foreach ($listeners as $listener) {
$eventManager->addEventListener($event, $listener);
}
}
$container->set('doctrine.dbal.default_connection', $connection);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment