Skip to content

Commit

Permalink
Prefer assertRaisesMessage over assertRaises
Browse files Browse the repository at this point in the history
  • Loading branch information
atombrella committed Mar 31, 2017
1 parent a0d29a9 commit b8cd00d
Show file tree
Hide file tree
Showing 39 changed files with 235 additions and 110 deletions.
2 changes: 1 addition & 1 deletion tests/admin_utils/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ def test_label_for_field(self):
"article"
)

with self.assertRaises(AttributeError):
with self.assertRaisesMessage(AttributeError, "Unable to lookup 'unknown' on Article"):
label_for_field("unknown", Article)

def test_callable(obj):
Expand Down
31 changes: 23 additions & 8 deletions tests/aggregation_regress/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,13 +430,23 @@ def test_decimal_aggregate_annotation_filter(self):

def test_field_error(self):
# Bad field requests in aggregates are caught and reported
with self.assertRaises(FieldError):
msg = (
"Cannot resolve keyword 'foo' into field. Choices are: authors, "
"contact, contact_id, hardbackbook, id, isbn, name, pages, price, "
"pubdate, publisher, publisher_id, rating, store, tags"
)
with self.assertRaisesMessage(FieldError, msg):
Book.objects.all().aggregate(num_authors=Count('foo'))

with self.assertRaises(FieldError):
with self.assertRaisesMessage(FieldError, msg):
Book.objects.all().annotate(num_authors=Count('foo'))

with self.assertRaises(FieldError):
msg = (
"Cannot resolve keyword 'foo' into field. Choices are: authors, "
"contact, contact_id, hardbackbook, id, isbn, name, num_authors, "
"pages, price, pubdate, publisher, publisher_id, rating, store, tags"
)
with self.assertRaisesMessage(FieldError, msg):
Book.objects.all().annotate(num_authors=Count('authors__id')).aggregate(Max('foo'))

def test_more(self):
Expand Down Expand Up @@ -737,19 +747,22 @@ def test_more_more(self):

def test_duplicate_alias(self):
# Regression for #11256 - duplicating a default alias raises ValueError.
with self.assertRaises(ValueError):
msg = "The named annotation 'authors__age__avg' conflicts with the default name for another annotation."
with self.assertRaisesMessage(ValueError, msg):
Book.objects.all().annotate(Avg('authors__age'), authors__age__avg=Avg('authors__age'))

def test_field_name_conflict(self):
# Regression for #11256 - providing an aggregate name
# that conflicts with a field name on the model raises ValueError
with self.assertRaises(ValueError):
msg = "The annotation 'age' conflicts with a field on the model."
with self.assertRaisesMessage(ValueError, msg):
Author.objects.annotate(age=Avg('friends__age'))

def test_m2m_name_conflict(self):
# Regression for #11256 - providing an aggregate name
# that conflicts with an m2m name on the model raises ValueError
with self.assertRaises(ValueError):
msg = "The annotation 'friends' conflicts with a field on the model."
with self.assertRaisesMessage(ValueError, msg):
Author.objects.annotate(friends=Count('friends'))

def test_values_queryset_non_conflict(self):
Expand Down Expand Up @@ -777,7 +790,8 @@ def test_values_queryset_non_conflict(self):
def test_reverse_relation_name_conflict(self):
# Regression for #11256 - providing an aggregate name
# that conflicts with a reverse-related name on the model raises ValueError
with self.assertRaises(ValueError):
msg = "The annotation 'book_contact_set' conflicts with a field on the model."
with self.assertRaisesMessage(ValueError, msg):
Author.objects.annotate(book_contact_set=Avg('friends__age'))

def test_pickle(self):
Expand Down Expand Up @@ -936,7 +950,8 @@ def test_more_more_more(self):

# Regression for #10766 - Shouldn't be able to reference an aggregate
# fields in an aggregate() call.
with self.assertRaises(FieldError):
msg = "Cannot compute Avg('mean_age'): 'mean_age' is an aggregate"
with self.assertRaisesMessage(FieldError, msg):
Book.objects.annotate(mean_age=Avg('authors__age')).annotate(Avg('mean_age'))

def test_empty_filter_count(self):
Expand Down
5 changes: 3 additions & 2 deletions tests/basic/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ def test_eq(self):
def test_hash(self):
# Value based on PK
self.assertEqual(hash(Article(id=1)), hash(1))
with self.assertRaises(TypeError):
with self.assertRaisesMessage(TypeError, 'Model instances without primary key value are unhashable'):
# No PK value -> unhashable (because save() would then change
# hash)
hash(Article())
Expand Down Expand Up @@ -688,7 +688,8 @@ def test_refresh(self):

def test_unknown_kwarg(self):
s = SelfRef.objects.create()
with self.assertRaises(TypeError):
msg = "refresh_from_db() got an unexpected keyword argument 'unknown_kwarg'"
with self.assertRaisesMessage(TypeError, msg):
s.refresh_from_db(unknown_kwarg=10)

def test_refresh_fk(self):
Expand Down
6 changes: 5 additions & 1 deletion tests/custom_columns/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ def test_filter_first_name(self):
)

def test_field_error(self):
with self.assertRaises(FieldError):
msg = (
"Cannot resolve keyword 'firstname' into field. Choices are: "
"Author_ID, article, first_name, last_name, primary_set"
)
with self.assertRaisesMessage(FieldError, msg):
Author.objects.filter(firstname__exact="John")

def test_attribute_error(self):
Expand Down
5 changes: 3 additions & 2 deletions tests/custom_lookups/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -501,13 +501,14 @@ class LookupTransformCallOrderTests(TestCase):
def test_call_order(self):
with register_lookup(models.DateField, TrackCallsYearTransform):
# junk lookup - tries lookup, then transform, then fails
with self.assertRaises(FieldError):
msg = "Unsupported lookup 'junk' for IntegerField or join on the field not permitted."
with self.assertRaisesMessage(FieldError, msg):
Author.objects.filter(birthdate__testyear__junk=2012)
self.assertEqual(TrackCallsYearTransform.call_order,
['lookup', 'transform'])
TrackCallsYearTransform.call_order = []
# junk transform - tries transform only, then fails
with self.assertRaises(FieldError):
with self.assertRaisesMessage(FieldError, msg):
Author.objects.filter(birthdate__testyear__junk__more_junk=2012)
self.assertEqual(TrackCallsYearTransform.call_order,
['transform'])
Expand Down
10 changes: 6 additions & 4 deletions tests/custom_managers/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ def test_queryset_copied_to_default(self):
# Public methods are copied
manager.public_method()
# Private methods are not copied
with self.assertRaises(AttributeError):
msg = "%r object has no attribute '_private_method'" % manager.__class__.__name__
with self.assertRaisesMessage(AttributeError, msg):
manager._private_method()

def test_manager_honors_queryset_only(self):
Expand All @@ -56,7 +57,8 @@ def test_manager_honors_queryset_only(self):
# Methods with queryset_only=False are copied even if they are private.
manager._optin_private_method()
# Methods with queryset_only=True aren't copied even if they are public.
with self.assertRaises(AttributeError):
msg = "%r object has no attribute 'optout_public_method'" % manager.__class__.__name__
with self.assertRaisesMessage(AttributeError, msg):
manager.optout_public_method()

def test_manager_use_queryset_methods(self):
Expand Down Expand Up @@ -90,7 +92,7 @@ def test_manager_attributes(self):
querysets.
"""
Person.custom_queryset_custom_manager.manager_only()
with self.assertRaises(AttributeError):
with self.assertRaisesMessage(AttributeError, "'CustomQuerySet' object has no attribute 'manager_only'"):
Person.custom_queryset_custom_manager.all().manager_only()

def test_queryset_and_manager(self):
Expand All @@ -113,7 +115,7 @@ def test_no_objects(self):
The default manager, "objects", doesn't exist, because a custom one
was provided.
"""
with self.assertRaises(AttributeError):
with self.assertRaisesMessage(AttributeError, "type object 'Book' has no attribute 'objects'"):
Book.objects

def test_filtering(self):
Expand Down
2 changes: 1 addition & 1 deletion tests/custom_pk/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ def test_pk_attributes(self):
# Or we can use the real attribute name for the primary key:
self.assertEqual(e.employee_code, 123)

with self.assertRaises(AttributeError):
with self.assertRaisesMessage(AttributeError, "'Employee' object has no attribute 'id'"):
e.id

def test_in_bulk(self):
Expand Down
8 changes: 5 additions & 3 deletions tests/distinct_on_fields/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,16 +97,18 @@ def test_basic_distinct_on(self):

def test_distinct_not_implemented_checks(self):
# distinct + annotate not allowed
with self.assertRaises(NotImplementedError):
msg = 'annotate() + distinct(fields) is not implemented.'
with self.assertRaisesMessage(NotImplementedError, msg):
Celebrity.objects.annotate(Max('id')).distinct('id')[0]
with self.assertRaises(NotImplementedError):
with self.assertRaisesMessage(NotImplementedError, msg):
Celebrity.objects.distinct('id').annotate(Max('id'))[0]

# However this check is done only when the query executes, so you
# can use distinct() to remove the fields before execution.
Celebrity.objects.distinct('id').annotate(Max('id')).distinct()[0]
# distinct + aggregate not allowed
with self.assertRaises(NotImplementedError):
msg = 'aggregate() + distinct(fields) not implemented.'
with self.assertRaisesMessage(NotImplementedError, msg):
Celebrity.objects.distinct('id').aggregate(Max('id'))

def test_distinct_on_in_ordered_subquery(self):
Expand Down
9 changes: 6 additions & 3 deletions tests/expressions/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,8 @@ def test_filter_with_join(self):
)

with transaction.atomic():
with self.assertRaises(FieldError):
msg = "Joined field references are not permitted in this query"
with self.assertRaisesMessage(FieldError, msg):
Company.objects.exclude(
ceo__firstname=F('point_of_contact__firstname')
).update(name=F('point_of_contact__lastname'))
Expand Down Expand Up @@ -281,7 +282,8 @@ def test_new_object_create(self):

def test_object_create_with_aggregate(self):
# Aggregates are not allowed when inserting new data
with self.assertRaisesMessage(FieldError, 'Aggregate functions are not allowed in this query'):
msg = 'Aggregate functions are not allowed in this query'
with self.assertRaisesMessage(FieldError, msg):
Company.objects.create(
name='Company', num_employees=Max(Value(1)), num_chairs=1,
ceo=Employee.objects.create(firstname="Just", lastname="Doit", salary=30),
Expand All @@ -300,7 +302,8 @@ def test():
test_gmbh.point_of_contact = test_gmbh.ceo
test_gmbh.save()
test_gmbh.name = F("ceo__last_name")
with self.assertRaises(FieldError):
msg = 'Joined field references are not permitted in this query'
with self.assertRaisesMessage(FieldError, msg):
test_gmbh.save()

def test_object_update_unsaved_objects(self):
Expand Down
18 changes: 11 additions & 7 deletions tests/flatpages_tests/test_templatetags.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,17 +128,21 @@ def test_parsing_errors(self):
def render(t):
return Template(t).render(Context())

with self.assertRaises(TemplateSyntaxError):
msg = (
"get_flatpages expects a syntax of get_flatpages "
"['url_starts_with'] [for user] as context_name"
)
with self.assertRaisesMessage(TemplateSyntaxError, msg):
render("{% load flatpages %}{% get_flatpages %}")
with self.assertRaises(TemplateSyntaxError):
with self.assertRaisesMessage(TemplateSyntaxError, msg):
render("{% load flatpages %}{% get_flatpages as %}")
with self.assertRaises(TemplateSyntaxError):
with self.assertRaisesMessage(TemplateSyntaxError, msg):
render("{% load flatpages %}{% get_flatpages cheesecake flatpages %}")
with self.assertRaises(TemplateSyntaxError):
with self.assertRaisesMessage(TemplateSyntaxError, msg):
render("{% load flatpages %}{% get_flatpages as flatpages asdf %}")
with self.assertRaises(TemplateSyntaxError):
with self.assertRaisesMessage(TemplateSyntaxError, msg):
render("{% load flatpages %}{% get_flatpages cheesecake user as flatpages %}")
with self.assertRaises(TemplateSyntaxError):
with self.assertRaisesMessage(TemplateSyntaxError, msg):
render("{% load flatpages %}{% get_flatpages for user as flatpages asdf %}")
with self.assertRaises(TemplateSyntaxError):
with self.assertRaisesMessage(TemplateSyntaxError, msg):
render("{% load flatpages %}{% get_flatpages prefix for user as flatpages asdf %}")
14 changes: 12 additions & 2 deletions tests/foreign_object/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,12 @@ def test_foreign_key_related_query_name(self):
ArticleTag.objects.create(article=a1, name="foo")
self.assertEqual(Article.objects.filter(tag__name="foo").count(), 1)
self.assertEqual(Article.objects.filter(tag__name="bar").count(), 0)
with self.assertRaises(FieldError):
msg = (
"Cannot resolve keyword 'tags' into field. Choices are: "
"active_translation, active_translation_q, articletranslation, "
"id, idea_things, newsarticle, pub_date, tag"
)
with self.assertRaisesMessage(FieldError, msg):
Article.objects.filter(tags__name="foo")

def test_many_to_many_related_query_name(self):
Expand All @@ -378,7 +383,12 @@ def test_many_to_many_related_query_name(self):
a1.ideas.add(i1)
self.assertEqual(Article.objects.filter(idea_things__name="idea1").count(), 1)
self.assertEqual(Article.objects.filter(idea_things__name="idea2").count(), 0)
with self.assertRaises(FieldError):
msg = (
"Cannot resolve keyword 'ideas' into field. Choices are: "
"active_translation, active_translation_q, articletranslation, "
"id, idea_things, newsarticle, pub_date, tag"
)
with self.assertRaisesMessage(FieldError, msg):
Article.objects.filter(ideas__name="idea1")

@translation.override('fi')
Expand Down
7 changes: 4 additions & 3 deletions tests/forms_tests/field_tests/test_charfield.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,12 @@ def test_charfield_length_not_int(self):
Setting min_length or max_length to something that is not a number
raises an exception.
"""
with self.assertRaises(ValueError):
msg = "invalid literal for int() with base 10: 'a'"
with self.assertRaisesMessage(ValueError, msg):
CharField(min_length='a')
with self.assertRaises(ValueError):
with self.assertRaisesMessage(ValueError, msg):
CharField(max_length='a')
with self.assertRaises(ValueError):
with self.assertRaisesMessage(ValueError, msg):
CharField('a')

def test_charfield_widget_attrs(self):
Expand Down
3 changes: 2 additions & 1 deletion tests/forms_tests/field_tests/test_uuidfield.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ def test_uuidfield_2(self):

def test_uuidfield_3(self):
field = UUIDField()
with self.assertRaises(ValidationError) as cm:
msg = 'Enter a valid UUID.'
with self.assertRaisesMessage(ValidationError, msg) as cm:
field.clean('550e8400')
self.assertEqual(cm.exception.messages[0], 'Enter a valid UUID.')

Expand Down
7 changes: 6 additions & 1 deletion tests/generic_relations/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,12 @@ def test_assign_with_queryset(self):

def test_generic_relation_related_name_default(self):
# GenericRelation isn't usable from the reverse side by default.
with self.assertRaises(FieldError):
msg = (
"Cannot resolve keyword 'vegetable' into field. Choices are: "
"animal, content_object, content_type, content_type_id, id, "
"manualpk, object_id, tag, valuabletaggeditem"
)
with self.assertRaisesMessage(FieldError, msg):
TaggedItem.objects.filter(vegetable__isnull=True)

def test_multiple_gfk(self):
Expand Down
3 changes: 2 additions & 1 deletion tests/generic_views/test_edit.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@ def test_create_with_special_properties(self):
self.assertQuerysetEqual(Author.objects.all(), ['<Author: Randall Munroe>'])

def test_create_without_redirect(self):
with self.assertRaises(ImproperlyConfigured):
msg = 'No URL to redirect to. Either provide a url or define a get_absolute_url method on the Model.'
with self.assertRaisesMessage(ImproperlyConfigured, msg):
self.client.post('/edit/authors/create/naive/', {'name': 'Randall Munroe', 'slug': 'randall-munroe'})

def test_create_restricted(self):
Expand Down
3 changes: 2 additions & 1 deletion tests/get_earliest_or_latest/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ def test_latest_manual(self):
# "get_latest_by" set -- just pass in the field name manually.
Person.objects.create(name="Ralph", birthday=datetime(1950, 1, 1))
p2 = Person.objects.create(name="Stephanie", birthday=datetime(1960, 2, 3))
with self.assertRaises(AssertionError):
msg = "earliest() and latest() require either a field_name parameter or 'get_latest_by' in the model"
with self.assertRaisesMessage(AssertionError, msg):
Person.objects.latest()
self.assertEqual(Person.objects.latest("birthday"), p2)

Expand Down
17 changes: 13 additions & 4 deletions tests/lookup/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,11 @@ def test_values(self):
# However, an exception FieldDoesNotExist will be thrown if you specify
# a nonexistent field name in values() (a field that is neither in the
# model nor in extra(select)).
with self.assertRaises(FieldError):
msg = (
"Cannot resolve keyword 'id_plus_two' into field. Choices are: "
"author, author_id, headline, id, id_plus_one, pub_date, tag"
)
with self.assertRaisesMessage(FieldError, msg):
Article.objects.extra(select={'id_plus_one': 'id + 1'}).values('id', 'id_plus_two')
# If you don't specify field names to values(), all are returned.
self.assertSequenceEqual(
Expand Down Expand Up @@ -682,11 +686,16 @@ def test_nonfield_lookups(self):
"""
A lookup query containing non-fields raises the proper exception.
"""
with self.assertRaises(FieldError):
msg = "Unsupported lookup 'blahblah' for CharField or join on the field not permitted."
with self.assertRaisesMessage(FieldError, msg):
Article.objects.filter(headline__blahblah=99)
with self.assertRaises(FieldError):
with self.assertRaisesMessage(FieldError, msg):
Article.objects.filter(headline__blahblah__exact=99)
with self.assertRaises(FieldError):
msg = (
"Cannot resolve keyword 'blahblah' into field. Choices are: "
"author, author_id, headline, id, pub_date, tag"
)
with self.assertRaisesMessage(FieldError, msg):
Article.objects.filter(blahblah=99)

def test_lookup_collision(self):
Expand Down
2 changes: 1 addition & 1 deletion tests/m2m_regress/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def test_assigning_invalid_data_to_m2m_doesnt_clear_existing_relations(self):
c1 = TagCollection.objects.create(name='c1')
c1.tags.set([t1, t2])

with self.assertRaises(TypeError):
with self.assertRaisesMessage(TypeError, "'int' object is not iterable"):
c1.tags.set(7)

c1.refresh_from_db()
Expand Down
3 changes: 2 additions & 1 deletion tests/model_fields/test_decimalfield.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ def test_to_python(self):
f = models.DecimalField(max_digits=4, decimal_places=2)
self.assertEqual(f.to_python(3), Decimal('3'))
self.assertEqual(f.to_python('3.14'), Decimal('3.14'))
with self.assertRaises(ValidationError):
msg = "'abc' value must be a decimal number."
with self.assertRaisesMessage(ValidationError, msg):
f.to_python('abc')

def test_default(self):
Expand Down

0 comments on commit b8cd00d

Please sign in to comment.