One of my attributes is a property where the setter calls a validation function that raises an exception if the new value is invalid:
pos.offset = 0
# @offset.setter calls validate(offset=0)
# PositionError: Offset may not be 0.
I'm trying to add a test to ensure that this fails. However, I can't figure out how to get assertRaises to work with an assignment.
The normal syntax of assertRaises requires a method, not an attribute/property:
self.assertRaises(PositionError, pos.offset, 0)
# TypeError: 'int' object is not callable
The other forms I've tried are invalid Python:
self.assertRaises(PositionError, pos.offset = 0)
# SyntaxError: Keyword can't be an expression
self.assertRaises(PositionError, lambda: pos.offset = 0)
# SyntaxError: lambda cannot contain assignment
How do I test failure of assignment to a property?
Note: Python 2.6, I know unittest has some new features in 2.7
There are two ways you can use assertRaises: using keyword arguments. Just pass the exception, the callable function and the parameters of the callable function as keyword arguments that will elicit the exception. Make a function call that should raise the exception with a context.
pytest. The pytest test runner supports the execution of unittest test cases.
If a method is not returning anything through the "return" statement (void method), it may return data through its arguments. In this case, you can test the data returned in any argument. Else if a method is not returning any data through its arguments, it may change values of its instance variables.
Internally, unittest. main() is using a few tricks to figure out the name of the module (source file) that contains the call to main() . It then imports this modules, examines it, gets a list of all classes and functions which could be tests (according the configuration) and then creates a test case for each of them.
When you want to use unittest
to test that an exception occurs in a block of code rather than just a function call, you can use assertRaises
as a context manager:
with self.assertRaises(PositionError):
pos.offset = 0
This use can be found in the unittest docs.
While this is not available in Python 2.6, and won't work for you as such (I just saw your note), I think it's worth including among the answers, as it's probably the clearer way to do this for python 2.7+.
Before Python 2.7, you want to use setattr(object, name, value)
(doc). This allows you to set a value to an attribute.
self.assertRaises(PositionError, setattr, pos, "offset", 0)
# ... ok
This should always work, because if the attribute is a property and thus "secretly" calls a function, it must be within a class. I don't think a standard assignment can fail (although an expression on the right side can fail, i.e. x = 1/0
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With