Python - test a property throws exception
Asked Answered
W

5

14

Given:

def test_to_check_exception_is_thrown(self):
    # Arrange
    c = Class()
    # Act and Assert
    self.assertRaises(NameError, c.do_something)

If do_something throws an exception the test passes.

But I have a property, and when I replace c.do_something with c.name = "Name" I get an error about my Test Module not being imported and Eclipse highlights the equals symbol.

How do I test a property throws an exception?

Edit:

setattr and getattr are new to me. They've certainly helped in this case, thanks.

Worker answered 14/1, 2010 at 17:38 Comment(0)
D
17

assertRaises expects a callable object. You can create a function and pass it:

obj = Class()
def setNameTest():
    obj.name = "Name"        
self.assertRaises(NameError, setNameTest)

Another possibility is to use setattr:

self.assertRaises(NameError, setattr, obj, "name", "Name")

Your original code raises a syntax error because assignment is a statement and cannot be placed inside an expression.

Drumbeat answered 14/1, 2010 at 17:43 Comment(1)
Since python 2.7+ should checkout @RaphaelAhrens answer below. It is a lot more pythonic https://mcmap.net/q/792910/-python-test-a-property-throws-exceptionRountree
D
18

Since Python 2.7 and 3.1 assertRaises() can be used as a context manager. See here for Python 2 and here for Python3.

So you can write your test with the with instruction like this:

def test_to_check_exception_is_thrown(self):
    c = Class()
    with self.assertRaises(NameError):
        c.name = "Name"
Dermatophyte answered 14/5, 2014 at 9:32 Comment(0)
D
17

assertRaises expects a callable object. You can create a function and pass it:

obj = Class()
def setNameTest():
    obj.name = "Name"        
self.assertRaises(NameError, setNameTest)

Another possibility is to use setattr:

self.assertRaises(NameError, setattr, obj, "name", "Name")

Your original code raises a syntax error because assignment is a statement and cannot be placed inside an expression.

Drumbeat answered 14/1, 2010 at 17:43 Comment(1)
Since python 2.7+ should checkout @RaphaelAhrens answer below. It is a lot more pythonic https://mcmap.net/q/792910/-python-test-a-property-throws-exceptionRountree
L
8

The second argument to assertRaises should be a callable.

An assignment statement (ie. class.name = "Name") is not a callable so it will not work. Use setattr to perform the assignment like so

self.assertRaises(NameError, setattr, myclass, "name", "Name")

Also, you can't assign to class since it's a keyword.

Leesen answered 14/1, 2010 at 17:46 Comment(0)
D
2

As @interjay stated, it is expecting a callable, but you don't really need to define a named function for this. A lambda will do it:

self.assertRaises(SomeException, lambda: my_instance.some_property)
Duress answered 7/7, 2017 at 13:43 Comment(1)
Coud you explain why this deserves a negative vote?, there might be a side effect I'm missing. ThanksDuress
O
-1

You're getting an error because it's a syntax error in Python to have an assignment inside another expression. For example:

>>> print(foo = 'bar')
------------------------------------------------------------
   File "<ipython console>", line 1
     print(foo = 'bar')
               ^
SyntaxError: invalid syntax

But doing it in two steps works fine:

>>> foo = 'bar'
>>> print(foo)
bar

To test that a property throws an exception, use a try block:

try:
   object.property = 'error'
except ExpectedError:
   test_passes()
else:
   test_fails()
Olodort answered 14/1, 2010 at 17:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.