From 67c063e6d55131358b81fc28bc7f62ca24295157 Mon Sep 17 00:00:00 2001
From: Claude Paroz <claude@2xlibre.net>
Date: Sat, 9 May 2015 16:33:58 +0200
Subject: [PATCH] Mocked db.connections in test_runner tests

---
 tests/test_runner/tests.py | 160 ++++++++++++++++---------------------
 1 file changed, 69 insertions(+), 91 deletions(-)

diff --git a/tests/test_runner/tests.py b/tests/test_runner/tests.py
index a9ae782f86..fba8e44e02 100644
--- a/tests/test_runner/tests.py
+++ b/tests/test_runner/tests.py
@@ -11,7 +11,6 @@ from django import db
 from django.conf import settings
 from django.core.exceptions import ImproperlyConfigured
 from django.core.management import call_command
-from django.db.backends.dummy.base import DatabaseCreation
 from django.test import (
     TestCase, TransactionTestCase, mock, skipUnlessDBFeature, testcases,
 )
@@ -211,29 +210,28 @@ class Sqlite3InMemoryTestDbs(TestCase):
                          "This is an sqlite-specific issue")
     def test_transaction_support(self):
         """Ticket #16329: sqlite3 in-memory test databases"""
-        old_db_connections = db.connections
         for option_key, option_value in (
                 ('NAME', ':memory:'), ('TEST', {'NAME': ':memory:'})):
-            try:
-                db.connections = db.ConnectionHandler({
-                    'default': {
-                        'ENGINE': 'django.db.backends.sqlite3',
-                        option_key: option_value,
-                    },
-                    'other': {
-                        'ENGINE': 'django.db.backends.sqlite3',
-                        option_key: option_value,
-                    },
-                })
-                other = db.connections['other']
-                DiscoverRunner(verbosity=0).setup_databases()
-                msg = "DATABASES setting '%s' option set to sqlite3's ':memory:' value shouldn't interfere with transaction support detection." % option_key
-                # Transaction support should be properly initialized for the 'other' DB
-                self.assertTrue(other.features.supports_transactions, msg)
-                # And all the DBs should report that they support transactions
-                self.assertTrue(connections_support_transactions(), msg)
-            finally:
-                db.connections = old_db_connections
+            tested_connections = db.ConnectionHandler({
+                'default': {
+                    'ENGINE': 'django.db.backends.sqlite3',
+                    option_key: option_value,
+                },
+                'other': {
+                    'ENGINE': 'django.db.backends.sqlite3',
+                    option_key: option_value,
+                },
+            })
+            with mock.patch('django.db.connections', new=tested_connections):
+                with mock.patch('django.test.testcases.connections', new=tested_connections):
+                    other = tested_connections['other']
+                    DiscoverRunner(verbosity=0).setup_databases()
+                    msg = ("DATABASES setting '%s' option set to sqlite3's ':memory:' value "
+                           "shouldn't interfere with transaction support detection." % option_key)
+                    # Transaction support should be properly initialized for the 'other' DB
+                    self.assertTrue(other.features.supports_transactions, msg)
+                    # And all the DBs should report that they support transactions
+                    self.assertTrue(connections_support_transactions(), msg)
 
 
 class DummyBackendTest(unittest.TestCase):
@@ -241,17 +239,15 @@ class DummyBackendTest(unittest.TestCase):
         """
         Test that setup_databases() doesn't fail with dummy database backend.
         """
-        runner_instance = DiscoverRunner(verbosity=0)
-        old_db_connections = db.connections
-        try:
-            db.connections = db.ConnectionHandler({})
-            old_config = runner_instance.setup_databases()
-            runner_instance.teardown_databases(old_config)
-        except Exception as e:
-            self.fail("setup_databases/teardown_databases unexpectedly raised "
-                      "an error: %s" % e)
-        finally:
-            db.connections = old_db_connections
+        tested_connections = db.ConnectionHandler({})
+        with mock.patch('django.db.connections', new=tested_connections):
+            runner_instance = DiscoverRunner(verbosity=0)
+            try:
+                old_config = runner_instance.setup_databases()
+                runner_instance.teardown_databases(old_config)
+            except Exception as e:
+                self.fail("setup_databases/teardown_databases unexpectedly raised "
+                          "an error: %s" % e)
 
 
 class AliasedDefaultTestSetupTest(unittest.TestCase):
@@ -259,51 +255,31 @@ class AliasedDefaultTestSetupTest(unittest.TestCase):
         """
         Test that setup_datebases() doesn't fail when 'default' is aliased
         """
-        runner_instance = DiscoverRunner(verbosity=0)
-        old_db_connections = db.connections
-        try:
-            db.connections = db.ConnectionHandler({
-                'default': {
-                    'NAME': 'dummy'
-                },
-                'aliased': {
-                    'NAME': 'dummy'
-                }
-            })
-            old_config = runner_instance.setup_databases()
-            runner_instance.teardown_databases(old_config)
-        except Exception as e:
-            self.fail("setup_databases/teardown_databases unexpectedly raised "
-                      "an error: %s" % e)
-        finally:
-            db.connections = old_db_connections
+        tested_connections = db.ConnectionHandler({
+            'default': {
+                'NAME': 'dummy'
+            },
+            'aliased': {
+                'NAME': 'dummy'
+            }
+        })
+        with mock.patch('django.db.connections', new=tested_connections):
+            runner_instance = DiscoverRunner(verbosity=0)
+            try:
+                old_config = runner_instance.setup_databases()
+                runner_instance.teardown_databases(old_config)
+            except Exception as e:
+                self.fail("setup_databases/teardown_databases unexpectedly raised "
+                          "an error: %s" % e)
 
 
 class SetupDatabasesTests(unittest.TestCase):
 
     def setUp(self):
-        self._old_db_connections = db.connections
-        self._old_destroy_test_db = DatabaseCreation.destroy_test_db
-        self._old_create_test_db = DatabaseCreation.create_test_db
         self.runner_instance = DiscoverRunner(verbosity=0)
 
-    def tearDown(self):
-        DatabaseCreation.create_test_db = self._old_create_test_db
-        DatabaseCreation.destroy_test_db = self._old_destroy_test_db
-        db.connections = self._old_db_connections
-
     def test_setup_aliased_databases(self):
-        destroyed_names = []
-        DatabaseCreation.destroy_test_db = (
-            lambda self, old_database_name, verbosity=1, keepdb=False, serialize=True:
-            destroyed_names.append(old_database_name)
-        )
-        DatabaseCreation.create_test_db = (
-            lambda self, verbosity=1, autoclobber=False, keepdb=False, serialize=True:
-            self._get_test_db_name()
-        )
-
-        db.connections = db.ConnectionHandler({
+        tested_connections = db.ConnectionHandler({
             'default': {
                 'ENGINE': 'django.db.backends.dummy',
                 'NAME': 'dbname',
@@ -314,13 +290,14 @@ class SetupDatabasesTests(unittest.TestCase):
             }
         })
 
-        old_config = self.runner_instance.setup_databases()
-        self.runner_instance.teardown_databases(old_config)
-
-        self.assertEqual(destroyed_names.count('dbname'), 1)
+        with mock.patch('django.db.backends.dummy.base.DatabaseCreation') as mocked_db_creation:
+            with mock.patch('django.db.connections', new=tested_connections):
+                old_config = self.runner_instance.setup_databases()
+                self.runner_instance.teardown_databases(old_config)
+        mocked_db_creation.return_value.destroy_test_db.assert_called_once_with('dbname', 0, False)
 
     def test_destroy_test_db_restores_db_name(self):
-        db.connections = db.ConnectionHandler({
+        tested_connections = db.ConnectionHandler({
             'default': {
                 'ENGINE': settings.DATABASES[db.DEFAULT_DB_ALIAS]["ENGINE"],
                 'NAME': 'xxx_test_database',
@@ -328,35 +305,36 @@ class SetupDatabasesTests(unittest.TestCase):
         })
         # Using the real current name as old_name to not mess with the test suite.
         old_name = settings.DATABASES[db.DEFAULT_DB_ALIAS]["NAME"]
-        db.connections['default'].creation.destroy_test_db(old_name, verbosity=0, keepdb=True)
-        self.assertEqual(db.connections['default'].settings_dict["NAME"], old_name)
+        with mock.patch('django.db.connections', new=tested_connections):
+            tested_connections['default'].creation.destroy_test_db(old_name, verbosity=0, keepdb=True)
+            self.assertEqual(tested_connections['default'].settings_dict["NAME"], old_name)
 
     def test_serialization(self):
-        serialize = []
-        DatabaseCreation.create_test_db = (
-            lambda *args, **kwargs: serialize.append(kwargs.get('serialize'))
-        )
-        db.connections = db.ConnectionHandler({
+        tested_connections = db.ConnectionHandler({
             'default': {
                 'ENGINE': 'django.db.backends.dummy',
             },
         })
-        self.runner_instance.setup_databases()
-        self.assertEqual(serialize, [True])
+        with mock.patch('django.db.backends.dummy.base.DatabaseCreation') as mocked_db_creation:
+            with mock.patch('django.db.connections', new=tested_connections):
+                self.runner_instance.setup_databases()
+        mocked_db_creation.return_value.create_test_db.assert_called_once_with(
+            0, autoclobber=False, serialize=True, keepdb=False
+        )
 
     def test_serialized_off(self):
-        serialize = []
-        DatabaseCreation.create_test_db = (
-            lambda *args, **kwargs: serialize.append(kwargs.get('serialize'))
-        )
-        db.connections = db.ConnectionHandler({
+        tested_connections = db.ConnectionHandler({
             'default': {
                 'ENGINE': 'django.db.backends.dummy',
                 'TEST': {'SERIALIZE': False},
             },
         })
-        self.runner_instance.setup_databases()
-        self.assertEqual(serialize, [False])
+        with mock.patch('django.db.backends.dummy.base.DatabaseCreation') as mocked_db_creation:
+            with mock.patch('django.db.connections', new=tested_connections):
+                self.runner_instance.setup_databases()
+        mocked_db_creation.return_value.create_test_db.assert_called_once_with(
+            0, autoclobber=False, serialize=False, keepdb=False
+        )
 
 
 class DeprecationDisplayTest(AdminScriptTestCase):