Fixed #29024 -- Made TestContextDecorator call disable() if setUp() raises an exception.

This commit is contained in:
Kamil 2018-08-17 22:30:27 +02:00 committed by Tim Graham
parent abd0ad7681
commit 3d4080f19c
2 changed files with 32 additions and 3 deletions

View File

@ -347,7 +347,11 @@ class TestContextDecorator:
context = self.enable() context = self.enable()
if self.attr_name: if self.attr_name:
setattr(inner_self, self.attr_name, context) setattr(inner_self, self.attr_name, context)
try:
decorated_setUp(inner_self) decorated_setUp(inner_self)
except Exception:
self.disable()
raise
def tearDown(inner_self): def tearDown(inner_self):
decorated_tearDown(inner_self) decorated_tearDown(inner_self)

View File

@ -19,8 +19,8 @@ from django.test import (
) )
from django.test.html import HTMLParseError, parse_html from django.test.html import HTMLParseError, parse_html
from django.test.utils import ( from django.test.utils import (
CaptureQueriesContext, isolate_apps, override_settings, CaptureQueriesContext, TestContextDecorator, isolate_apps,
setup_test_environment, override_settings, setup_test_environment,
) )
from django.urls import NoReverseMatch, reverse from django.urls import NoReverseMatch, reverse
@ -1221,3 +1221,28 @@ class IsolatedAppsTests(SimpleTestCase):
self.assertEqual(MethodDecoration._meta.apps, method_apps) self.assertEqual(MethodDecoration._meta.apps, method_apps)
self.assertEqual(ContextManager._meta.apps, context_apps) self.assertEqual(ContextManager._meta.apps, context_apps)
self.assertEqual(NestedContextManager._meta.apps, nested_context_apps) self.assertEqual(NestedContextManager._meta.apps, nested_context_apps)
class DoNothingDecorator(TestContextDecorator):
def enable(self):
pass
def disable(self):
pass
class TestContextDecoratorTests(SimpleTestCase):
@mock.patch.object(DoNothingDecorator, 'disable')
def test_exception_in_setup(self, mock_disable):
"""An exception is setUp() is reraised after disable() is called."""
class ExceptionInSetUp(unittest.TestCase):
def setUp(self):
raise NotImplementedError('reraised')
decorator = DoNothingDecorator()
decorated_test_class = decorator.__call__(ExceptionInSetUp)()
self.assertFalse(mock_disable.called)
with self.assertRaisesMessage(NotImplementedError, 'reraised'):
decorated_test_class.setUp()
self.assertTrue(mock_disable.called)