Skip to content

Instantly share code, notes, and snippets.

@fntneves
Last active March 31, 2018 23:25
Show Gist options
  • Save fntneves/7f0b99767fce369919211148942eb297 to your computer and use it in GitHub Desktop.
Save fntneves/7f0b99767fce369919211148942eb297 to your computer and use it in GitHub Desktop.
A TestCase class that disables database events by temporarily replacing the EventDispatcher that has no listeners
<?php
namespace Tests\Feature;
use Tests\TestCase as BaseTestCase;
use Illuminate\Database\ConnectionInterface;
use Illuminate\Foundation\Testing\RefreshDatabase;
abstract class TestCase extends BaseTestCase
{
use RefreshDatabase;
private $currentDisabledDispatcher;
/**
* Begin a database transaction on the testing database.
*
* @return void
*/
public function beginDatabaseTransaction()
{
$database = $this->app->make('db');
foreach ($this->connectionsToTransact() as $name) {
$connection = $database->connection($name);
// Disable event dispatcher in order to avoid event dispatching
// that could interfer with the behavior of the application
// under test. Enable it as soon as transaction begins.
$this->disableEventDispatcher($connection);
$connection->beginTransaction();
$this->enableEventDispatcher($connection);
}
$this->beforeApplicationDestroyed(function () use ($database) {
foreach ($this->connectionsToTransact() as $name) {
$connection = $database->connection($name);
// Disable event dispatcher in order to avoid event dispatching
// that could interfer with the behavior of the application
// under test. Enable as soon as transaction rollbacks.
$this->disableEventDispatcher($connection);
$connection->rollBack();
$this->enableEventDispatcher($connection);
$connection->disconnect();
}
});
}
/**
* Disable the event dispatcher of the given connection.
*
* @param \Illuminate\Database\ConnectionInterface $connection
* @return void
*/
protected function disableEventDispatcher(ConnectionInterface $connection)
{
static $emptyDispatcher;
$emptyDispatcher = new \Illuminate\Events\Dispatcher;
$this->currentDisabledDispatcher = $connection->getEventDispatcher();
$connection->setEventDispatcher($emptyDispatcher);
}
/**
* Enable the event dispatcher of the given connection.
*
* @param \Illuminate\Database\ConnectionInterface $connection
* @return void
*/
protected function enableEventDispatcher(ConnectionInterface $connection)
{
$connection->setEventDispatcher($this->currentDisabledDispatcher);
$this->currentDisabledDispatcher = null;
}
}
@fntneves
Copy link
Author

This is an implementation of TestCase that achieves what is proposed here: laravel/ideas#1094

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment