Skip to content

Commit 0859db8

Browse files
Adding exception handler tests
1 parent dcfb2e6 commit 0859db8

File tree

1 file changed

+166
-0
lines changed

1 file changed

+166
-0
lines changed
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
2+
import pytest
3+
4+
from aws_lambda_powertools.event_handler.exception_handling import (
5+
ExceptionHandlerManager, # Assuming the class is in this module
6+
)
7+
8+
9+
@pytest.fixture
10+
def exception_manager() -> ExceptionHandlerManager:
11+
"""Fixture to provide a fresh ExceptionHandlerManager instance for each test."""
12+
return ExceptionHandlerManager()
13+
14+
# ----- Tests for exception_handler decorator -----
15+
16+
def test_decorator_registers_single_exception_handler(exception_manager):
17+
"""
18+
WHEN the exception_handler decorator is used with a single exception type
19+
GIVEN a function decorated with @manager.exception_handler(ValueError)
20+
THEN the function is registered as a handler for ValueError
21+
"""
22+
@exception_manager.exception_handler(ValueError)
23+
def handle_value_error(e):
24+
return "ValueError handled"
25+
26+
handlers = exception_manager.get_registered_handlers()
27+
assert ValueError in handlers
28+
assert handlers[ValueError] == handle_value_error
29+
30+
def test_decorator_registers_multiple_exception_handlers(exception_manager):
31+
"""
32+
GIVEN a function decorated with @manager.exception_handler([KeyError, TypeError])
33+
WHEN the exception_handler decorator is used with multiple exception types
34+
THEN the function is registered as a handler for both KeyError and TypeError
35+
"""
36+
@exception_manager.exception_handler([KeyError, TypeError])
37+
def handle_multiple_errors(e):
38+
return f"{type(e).__name__} handled"
39+
40+
handlers = exception_manager.get_registered_handlers()
41+
assert KeyError in handlers
42+
assert TypeError in handlers
43+
assert handlers[KeyError] == handle_multiple_errors
44+
assert handlers[TypeError] == handle_multiple_errors
45+
46+
def test_lookup_uses_inheritance_hierarchy(exception_manager):
47+
# GIVEN a handler has been registered for a base exception type
48+
@exception_manager.exception_handler(Exception)
49+
def handle_exception(e):
50+
return "Exception handled"
51+
52+
# WHEN lookup_exception_handler is called with a derived exception type
53+
# THEN the handler for the base exception is returned
54+
handler = exception_manager.lookup_exception_handler(ValueError)
55+
assert handler == handle_exception
56+
57+
def test_lookup_returns_none_for_unregistered_handler(exception_manager):
58+
"""
59+
GIVEN no handler has been registered for that type or its base classes
60+
WHEN lookup_exception_handler is called with an exception type
61+
THEN None is returned
62+
"""
63+
handler = exception_manager.lookup_exception_handler(ValueError)
64+
assert handler is None
65+
66+
def test_register_handler_for_multiple_exceptions(exception_manager):
67+
# GIVEN a valid handler function
68+
@exception_manager.exception_handler([ValueError, KeyError])
69+
def handle_error(e):
70+
return "Error handled"
71+
72+
# THEN the handler is properly registered for all exceptions in the list
73+
handlers = exception_manager.get_registered_handlers()
74+
assert KeyError in handlers
75+
assert TypeError in handlers
76+
assert handlers[KeyError] == handle_error
77+
assert handlers[TypeError] == handle_error
78+
79+
80+
def test_update_exception_handlers_with_dictionary(exception_manager):
81+
"""
82+
WHEN update_exception_handlers is called with a dictionary
83+
GIVEN the dictionary maps exception types to handler functions
84+
THEN all handlers in the dictionary are properly registered
85+
"""
86+
def handle_value_error(e):
87+
return "ValueError handled"
88+
89+
def handle_key_error(e):
90+
return "KeyError handled"
91+
92+
# Update with a dictionary of handlers
93+
exception_manager.update_exception_handlers({
94+
ValueError: handle_value_error,
95+
KeyError: handle_key_error,
96+
})
97+
98+
handlers = exception_manager.get_registered_handlers()
99+
assert ValueError in handlers
100+
assert KeyError in handlers
101+
assert handlers[ValueError] == handle_value_error
102+
assert handlers[KeyError] == handle_key_error
103+
104+
105+
def test_clear_handlers_removes_all_handlers(exception_manager):
106+
# GIVEN handlers have been registered
107+
@exception_manager.exception_handler([ValueError, KeyError])
108+
def handle_error(e):
109+
return "Error handled"
110+
111+
# Verify handlers are registered
112+
assert len(exception_manager.get_registered_handlers()) == 2
113+
114+
# WHEN clear_handlers is called
115+
exception_manager.clear_handlers()
116+
117+
# THEN all handlers are removed
118+
assert len(exception_manager.get_registered_handlers()) == 0
119+
120+
121+
def test_get_registered_handlers_returns_copy(exception_manager):
122+
# WHEN get_registered_handlers is called
123+
@exception_manager.exception_handler(ValueError)
124+
def handle_error(e):
125+
return "Error handled"
126+
127+
# GIVEN handlers have been registered
128+
handlers_copy = exception_manager.get_registered_handlers()
129+
130+
# THEN a copy of the handlers dictionary is returned that doesn't affect the original
131+
handlers_copy[KeyError] = lambda e: "Not registered properly"
132+
assert KeyError not in exception_manager.get_registered_handlers()
133+
134+
135+
def test_handler_executes_correctly(exception_manager):
136+
# GIVEN a registered handler is executed with an exception
137+
@exception_manager.exception_handler(ValueError)
138+
def handle_value_error(e):
139+
return f"Handled: {str(e)}"
140+
141+
# WHEN an exception happens
142+
# THEN the handler processes the exception correctly
143+
try:
144+
raise ValueError("Test error")
145+
except Exception as e:
146+
handler = exception_manager.lookup_exception_handler(type(e))
147+
result = handler(e)
148+
assert result == "Handled: Test error"
149+
150+
def test_registering_new_handler_overrides_previous(exception_manager):
151+
# WHEN a new handler is registered for an exception type
152+
@exception_manager.exception_handler(ValueError)
153+
def first_handler(e):
154+
return "First handler"
155+
156+
# GIVEN a handler was already registered for that type
157+
@exception_manager.exception_handler(ValueError)
158+
def second_handler(e):
159+
return "Second handler"
160+
161+
162+
# THEN the new handler replaces the previous one
163+
# Check that the second handler overrode the first
164+
handler = exception_manager.lookup_exception_handler(ValueError)
165+
assert handler == second_handler
166+
assert handler != first_handler

0 commit comments

Comments
 (0)