Exercise 1: A Failure-Simulating Stub — Possible Solution ==================================================================== THE NEW STUB ------------------------------ class FailingStubNotificationSender: def send(self, email, message): return None # simulates a failed send RESULT ------------------------------ test_registration_succeeds_even_when_notification_fails: PASS service.users == ["gina@example.com"] (True) result['registered'] is True (True) Registration succeeds and the user is added to the list even though the stub's send() "failed" (returned None), because register() never inspects send()'s own return value at all. WHY THIS WORKS AS AN ANSWER ------------------------------ This is a stub in the precise sense this chapter defined it: it returns a canned value (here, None instead of "SENT") with no real logic behind it, purely to control what the code under test observes. Using it surfaces a genuine (if minor) design fact about UserRegistrationService: it currently has no failure-handling path for a failed notification at all. That's not a bug this exercise set out to find, but it's a legitimate side effect of writing a stub for the failure case - stubs are often exactly how a missing error-handling path gets noticed, since they make an otherwise-rare failure trivial to force on demand.