diff --git a/django/contrib/admin/helpers.py b/django/contrib/admin/helpers.py index 2e7a20a49b0..aea13b94d77 100644 --- a/django/contrib/admin/helpers.py +++ b/django/contrib/admin/helpers.py @@ -83,6 +83,10 @@ class AdminForm: def non_field_errors(self): return self.form.non_field_errors + @property + def is_bound(self): + return self.form.is_bound + @property def media(self): media = self.form.media @@ -437,6 +441,10 @@ class InlineAdminFormSet: def non_form_errors(self): return self.formset.non_form_errors + @property + def is_bound(self): + return self.formset.is_bound + @property def media(self): media = self.opts.media + self.formset.media diff --git a/django/test/testcases.py b/django/test/testcases.py index 14416807be0..0d24bf0d408 100644 --- a/django/test/testcases.py +++ b/django/test/testcases.py @@ -595,6 +595,12 @@ class SimpleTestCase(unittest.TestCase): for i, context in enumerate(contexts): if form not in context: continue + if not context[form].is_bound: + form_repr = repr(context[form]) + self.fail( + f"{msg_prefix}The form {form_repr} is not bound, it will never " + f"have any errors." + ) found_form = True for err in errors: if field: @@ -680,6 +686,12 @@ class SimpleTestCase(unittest.TestCase): for i, context in enumerate(contexts): if formset not in context or not hasattr(context[formset], "forms"): continue + if not context[formset].is_bound: + formset_repr = repr(context[formset]) + self.fail( + f"{msg_prefix}The formset {formset_repr} is not bound, it will " + f"never have any errors." + ) found_formset = True for err in errors: if field is not None: diff --git a/tests/test_utils/tests.py b/tests/test_utils/tests.py index c755d356eef..bfc9633122f 100644 --- a/tests/test_utils/tests.py +++ b/tests/test_utils/tests.py @@ -1454,8 +1454,13 @@ class AssertFormErrorTests(SimpleTestCase): self.assertFormError(response, "form", "field", "invalid value") def test_empty_errors_unbound_form(self): + msg = ( + "The form is not " + "bound, it will never have any errors." + ) response = mock.Mock(context=[{"form": TestForm()}]) - self.assertFormError(response, "form", "field", []) + with self.assertRaisesMessage(AssertionError, msg): + self.assertFormError(response, "form", "field", []) def test_empty_errors_valid_form(self): response = mock.Mock(context=[{"form": TestForm.valid()}]) @@ -1590,8 +1595,13 @@ class AssertFormsetErrorTests(SimpleTestCase): self.assertFormsetError(response, "formset", 0, "field", "invalid value") def test_empty_errors_unbound_formset(self): + msg = ( + "The formset is not " + "bound, it will never have any errors." + ) response = mock.Mock(context=[{"formset": TestFormset()}]) - self.assertFormsetError(response, "formset", 0, "field", []) + with self.assertRaisesMessage(AssertionError, msg): + self.assertFormsetError(response, "formset", 0, "field", []) def test_empty_errors_valid_formset(self): response = mock.Mock(context=[{}, {"formset": TestFormset.valid()}])