diff --git a/django/db/backends/base/creation.py b/django/db/backends/base/creation.py index 7c11465f943e..ed2b0738a5a1 100644 --- a/django/db/backends/base/creation.py +++ b/django/db/backends/base/creation.py @@ -22,6 +22,12 @@ class BaseDatabaseCreation: destruction of the test database. """ + # If this backend's destroy_test_db() closes the database connection, this + # attribute must be set to the name of the connection closing method (e.g. + # "close" on Oracle, "close_pool" on MongoDB) to avoid failures in some + # backends tests. + destroy_test_db_connection_close_method = None + def __init__(self, connection): self.connection = connection diff --git a/django/db/backends/oracle/creation.py b/django/db/backends/oracle/creation.py index efbec14d6eee..d36177b7e143 100644 --- a/django/db/backends/oracle/creation.py +++ b/django/db/backends/oracle/creation.py @@ -10,6 +10,8 @@ class DatabaseCreation(BaseDatabaseCreation): + destroy_test_db_connection_close_method = "close" + @cached_property def _maindb_connection(self): """ diff --git a/tests/backends/base/test_creation.py b/tests/backends/base/test_creation.py index 202d8e1b40d5..2542407f0bc4 100644 --- a/tests/backends/base/test_creation.py +++ b/tests/backends/base/test_creation.py @@ -67,6 +67,13 @@ def test_custom_test_name_with_test_prefix(self): class TestDbCreationTests(SimpleTestCase): available_apps = ["backends.base.app_unmigrated"] + @staticmethod + def patch_close_connection(creation): + # If DatabaseCreation.destroy_test_db() closes the database connection, + # that behavior must be disabled to prevent each test from crashing. + if close_method_name := creation.destroy_test_db_connection_close_method: + setattr(creation.connection, close_method_name, mock.Mock()) + @mock.patch("django.db.migrations.executor.MigrationExecutor.migrate") def test_migrate_test_setting_false( self, mocked_migrate, mocked_sync_apps, *mocked_objects @@ -74,9 +81,7 @@ def test_migrate_test_setting_false( test_connection = get_connection_copy() test_connection.settings_dict["TEST"]["MIGRATE"] = False creation = test_connection.creation_class(test_connection) - if connection.vendor == "oracle": - # Don't close connection on Oracle. - creation.connection.close = mock.Mock() + self.patch_close_connection(creation) old_database_name = test_connection.settings_dict["NAME"] try: with mock.patch.object(creation, "_create_test_db"): @@ -104,9 +109,7 @@ def test_migrate_test_setting_false_ensure_schema( test_connection = get_connection_copy() test_connection.settings_dict["TEST"]["MIGRATE"] = False creation = test_connection.creation_class(test_connection) - if connection.vendor == "oracle": - # Don't close connection on Oracle. - creation.connection.close = mock.Mock() + self.patch_close_connection(creation) old_database_name = test_connection.settings_dict["NAME"] try: with mock.patch.object(creation, "_create_test_db"): @@ -128,9 +131,7 @@ def test_migrate_test_setting_true( test_connection = get_connection_copy() test_connection.settings_dict["TEST"]["MIGRATE"] = True creation = test_connection.creation_class(test_connection) - if connection.vendor == "oracle": - # Don't close connection on Oracle. - creation.connection.close = mock.Mock() + self.patch_close_connection(creation) old_database_name = test_connection.settings_dict["NAME"] try: with mock.patch.object(creation, "_create_test_db"): @@ -158,9 +159,7 @@ def test_mark_expected_failures_and_skips_call( """ test_connection = get_connection_copy() creation = test_connection.creation_class(test_connection) - if connection.vendor == "oracle": - # Don't close connection on Oracle. - creation.connection.close = mock.Mock() + self.patch_close_connection(creation) old_database_name = test_connection.settings_dict["NAME"] try: with mock.patch.object(creation, "_create_test_db"): @@ -175,9 +174,7 @@ def test_mark_expected_failures_and_skips_call( def test_serialize_deprecation(self, serialize_db_to_string, *mocked_objects): test_connection = get_connection_copy() creation = test_connection.creation_class(test_connection) - if connection.vendor == "oracle": - # Don't close connection on Oracle. - creation.connection.close = mock.Mock() + self.patch_close_connection(creation) old_database_name = test_connection.settings_dict["NAME"] msg = ( "DatabaseCreation.create_test_db(serialize) is deprecated. Call "