22👍
I think its because assert raises only accepts a callable. It evalutes to see if the callable raises an exception, not if the statement itself does.
self.assertRaises(AttributeError, getattr, branch[0], "childrennodes")
should work.
EDIT:
As THC4k correctly says it gathers the statements at collection time and will error then, not at testing time.
Also this is a reason why I like nose, it has a decorator (raises) that is useful and clearer for these kind of tests.
@raises(AttributeError)
def test_1(self)
branch[0].childrennodes
58👍
When the test is running, before calling self.assertRaises, Python needs to find the value of all the method’s arguments. In doing so, it evaluates branch[0].children_nodes
, which raises an AttributeError. Since we haven’t invoked assertRaises yet, this exception is not caught, causing the test to fail.
The solution is to wrap branch[0].children_nodes
in a function or a lambda:
self.assertRaises(AttributeError, lambda: branch[0].children_nodes)
assertRaises can also be used as a context manager (Since Python 2.7, or in PyPI package ‘unittest2’):
with self.assertRaises(AttributeError):
branch[0].children_nodes
# etc
This is nice because it can be used on arbitrary blocks of code in the middle of a test, rather than having to create a new function just to define the block of code to which it applies.
It can give you access to the raised exception for further processing, if needed:
with self.assertRaises(AttributeError) as cm:
branch[0].children_nodes
self.assertEquals(cm.exception.special_attribute, 123)
- [Django]-Execute code in Django after response has been sent to the client
- [Django]-Django – present current date and time in template
- [Django]-Django: Detect database backend
4👍
pytest also has a similar context manager:
from pytest import raises
def test_raising():
with raises(AttributeError):
branch[0].childrennodes
- [Django]-How to properly use the "choices" field option in Django
- [Django]-Is there a way to list Django signals?
- [Django]-What base_name parameter do I need in my route to make this Django API work?