You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In the sample below exceptions that are raised through observe cannot be caught in unit tests. It's expected behavior, but it may be surprising to some.
import unittest
from traits.api import HasTraits, Int, observe
class Person(HasTraits):
age = Int()
@observe("age")
def update_age(self, event):
if self.age > 15:
print("Raising an exception")
raise ValueError("I do not want to get old")
class TestPerson(unittest.TestCase):
def test_update_age(self):
# given
steve = Person(age=10)
# when / then
with self.assertRaises(ValueError) as err:
steve.age = 18
self.assertIn("I do not want to get old", str(err.exception))
The following explanation from @mdickinson could be cleaned up and integrated in the docs:
There are mechanisms that allow exceptions in observe handlers to be propagated; that's sometimes useful during testing.
But raising an exception in an observer, while it might be tempting, isn't really a terribly useful thing to do - there's no sensible place for that exception to be propagated to.
IOW, an exception raised in an observer is almost always a coding bug.
In particular, you should never try to use observers for validation of an assignment to a trait - that doesn't work, because the assignment has already happened.
For testing and debugging, see https://docs.enthought.com/traits/traits_user_manual/debugging.html#re-raising-exceptions-in-change-handlers, and in particular push_exception_handler.
Note that there are two versions of push_exception_handler: one for on_trait_change and one for observe, so you need to use both if you want to catch all exceptions.
But beware doing this in tests by default, since now your test logic isn't necessarily exercising the same code paths that your business logic is.
It's quite possible to end up with broken business logic that passes test cases as a result.
In the sample below exceptions that are raised through
observe
cannot be caught in unit tests. It's expected behavior, but it may be surprising to some.The following explanation from @mdickinson could be cleaned up and integrated in the docs:
There are mechanisms that allow exceptions in observe handlers to be propagated; that's sometimes useful during testing.
But raising an exception in an observer, while it might be tempting, isn't really a terribly useful thing to do - there's no sensible place for that exception to be propagated to.
IOW, an exception raised in an observer is almost always a coding bug.
In particular, you should never try to use observers for validation of an assignment to a trait - that doesn't work, because the assignment has already happened.
For testing and debugging, see https://docs.enthought.com/traits/traits_user_manual/debugging.html#re-raising-exceptions-in-change-handlers, and in particular push_exception_handler.
Note that there are two versions of
push_exception_handler
: one foron_trait_change
and one forobserve
, so you need to use both if you want to catch all exceptions.But beware doing this in tests by default, since now your test logic isn't necessarily exercising the same code paths that your business logic is.
It's quite possible to end up with broken business logic that passes test cases as a result.
Internal discussion thread: https://enthought.slack.com/archives/C024RRPHD/p1667297991245249
The text was updated successfully, but these errors were encountered: