class SharedDatabaseStateViolationTest
Same name and namespace in other branches
- 11.x core/tests/Drupal/KernelTests/SharedDatabaseStateViolationTest.php \Drupal\KernelTests\SharedDatabaseStateViolationTest
Tests how "KernelTestBase" reports shared database state violations.
Attributes
#[CoversClass(KernelTestBase::class)]
#[Group('PHPUnit')]
#[Group('Test')]
#[Group('KernelTests')]
#[RunTestsInSeparateProcesses]
#[ShareEnvironment]
Hierarchy
- class \Drupal\Tests\DrupalTestCase uses \Drupal\Tests\DrupalTestCaseTrait extends \PHPUnit\Framework\TestCase
- class \Drupal\KernelTests\KernelTestBase implements \Drupal\Core\DependencyInjection\ServiceProviderInterface uses \Drupal\KernelTests\AssertContentTrait, \Drupal\Tests\RandomGeneratorTrait, \Drupal\Tests\ConfigTestTrait, \Drupal\Tests\ExtensionListTestTrait, \Prophecy\PhpUnit\ProphecyTrait, \Drupal\Tests\BrowserHtmlDebugTrait, \Drupal\Tests\HttpKernelUiHelperTrait extends \Drupal\Tests\DrupalTestCase
- class \Drupal\KernelTests\SharedDatabaseStateViolationTest extends \Drupal\KernelTests\KernelTestBase
- class \Drupal\KernelTests\KernelTestBase implements \Drupal\Core\DependencyInjection\ServiceProviderInterface uses \Drupal\KernelTests\AssertContentTrait, \Drupal\Tests\RandomGeneratorTrait, \Drupal\Tests\ConfigTestTrait, \Drupal\Tests\ExtensionListTestTrait, \Prophecy\PhpUnit\ProphecyTrait, \Drupal\Tests\BrowserHtmlDebugTrait, \Drupal\Tests\HttpKernelUiHelperTrait extends \Drupal\Tests\DrupalTestCase
Expanded class hierarchy of SharedDatabaseStateViolationTest
File
-
core/
tests/ Drupal/ KernelTests/ SharedDatabaseStateViolationTest.php, line 16
Namespace
Drupal\KernelTestsView source
class SharedDatabaseStateViolationTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
protected static $modules = [
'system',
'user',
];
/**
* The name of a table belonging to the initial state.
*/
private const PROBE_TABLE = 'shared_state_violation_probe';
/**
* A table that a test method adds and does not remove.
*/
private const ADDED_TABLE = 'shared_state_violation_added';
/**
* Whether ::resetEnvironment() throws.
*/
private bool $failReset = FALSE;
/**
* The schema of the probe table.
*/
private const PROBE_SCHEMA = [
'fields' => [
'id' => [
'type' => 'int',
'not null' => TRUE,
],
],
'primary key' => [
'id',
],
];
/**
* {@inheritdoc}
*/
protected function setUpEnvironment() : void {
$this->installEntitySchema('user');
$this->installConfig([
'system',
]);
$connection = $this->container
->get('database');
$connection->schema()
->createTable(self::PROBE_TABLE, self::PROBE_SCHEMA);
$connection->insert(self::PROBE_TABLE)
->fields([
'id' => 1,
])
->execute();
}
/**
* Tests that dropping a table of the initial state is reported.
*/
public function testDroppedTableIsReported() : void {
$connection = $this->container
->get('database');
$connection->schema()
->dropTable(self::PROBE_TABLE);
$caught = NULL;
try {
$this->checkNoSharedTableWasDropped();
} catch (\RuntimeException $e) {
$caught = $e;
}
$this->assertNotNull($caught, 'Dropping a table of the initial state is reported.');
$this->assertStringContainsString(self::PROBE_TABLE, $caught->getMessage());
$this->assertStringContainsString('belongs to the shared environment', $caught->getMessage());
// Putting the table back is enough to let the check in ::tearDown() pass.
$connection->schema()
->createTable(self::PROBE_TABLE, self::PROBE_SCHEMA);
$connection->insert(self::PROBE_TABLE)
->fields([
'id' => 1,
])
->execute();
}
/**
* Tests that a table the test method added is dropped and reported.
*/
public function testAddedTableIsReported() : void {
$connection = $this->container
->get('database');
$connection->schema()
->createTable(self::ADDED_TABLE, self::PROBE_SCHEMA);
$caught = NULL;
try {
$this->checkNoTableWasLeftBehind();
} catch (\RuntimeException $e) {
$caught = $e;
}
// The table is kept for inspection, so removing it here is enough to let
// the check in ::tearDown() pass.
$this->assertTrue($connection->schema()
->tableExists(self::ADDED_TABLE), 'The table is kept.');
$connection->schema()
->dropTable(self::ADDED_TABLE);
$this->assertNotNull($caught, 'A table the test method added is reported.');
$this->assertStringContainsString(self::ADDED_TABLE, $caught->getMessage());
$this->assertStringContainsString('must remove what it added', $caught->getMessage());
}
/**
* Tests that a cleanup failing is recorded.
*/
public function testResetFailureIsRecorded() : void {
$connection = $this->container
->get('database');
$original = $connection->select(self::STATE_TABLE, 's')
->fields('s', [
'status',
'message',
'tables',
])
->execute()
->fetchAssoc();
// What ::tearDown() runs. ::resetEnvironment() throws below, so this
// records the reason and rethrows.
$this->failReset = TRUE;
$caught = NULL;
try {
$this->tearDownEnvironment();
} catch (\RuntimeException $e) {
$caught = $e;
}
$this->failReset = FALSE;
$record = $connection->select(self::STATE_TABLE, 's')
->fields('s', [
'status',
'message',
])
->execute()
->fetchAssoc();
// Put the record back, otherwise the following test methods would refuse
// to run, which is the behavior under test rather than a failure.
$connection->delete(self::STATE_TABLE)
->execute();
$connection->insert(self::STATE_TABLE)
->fields($original)
->execute();
$this->assertNotNull($caught, 'The failure of the cleanup is not swallowed.');
$this->assertSame('invalid', $record['status']);
$this->assertStringContainsString('::resetEnvironment() failed', $record['message']);
$this->assertStringContainsString('The cleanup failed.', $record['message']);
}
/**
* Tests that invalidating the state records the reason durably.
*/
public function testInvalidationRecordsTheReason() : void {
$connection = $this->container
->get('database');
$original = $connection->select(self::STATE_TABLE, 's')
->fields('s', [
'status',
'message',
'tables',
])
->execute()
->fetchAssoc();
$this->invalidateDatabaseState('Because of a reason.');
$record = $connection->select(self::STATE_TABLE, 's')
->fields('s', [
'status',
'message',
])
->execute()
->fetchAssoc();
$this->assertSame('invalid', $record['status']);
$this->assertSame('Because of a reason.', $record['message']);
// Put the record back, otherwise the following test methods would refuse to
// run, which is the behavior under test rather than a failure. The list of
// environment tables has to come back as well, because the test methods
// that follow compare against it.
$connection->delete(self::STATE_TABLE)
->execute();
$connection->insert(self::STATE_TABLE)
->fields($original)
->execute();
}
/**
* Tests that the previous restores of the state table succeeded.
*/
public function testFinal() : void {
$connection = $this->container
->get('database');
$record = $connection->select(self::STATE_TABLE, 's')
->fields('s', [
'status',
'message',
])
->execute()
->fetchAssoc();
$this->assertSame('ready', $record['status']);
}
/**
* {@inheritdoc}
*/
protected function resetEnvironment() : void {
parent::resetEnvironment();
if ($this->failReset) {
throw new \RuntimeException('The cleanup failed.');
}
}
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.