Python

Lesson 09

Dependency injection for testability

Pass collaborators into functions or classes so behavior can be tested without patching global modules.

Good Code

notifications.py
def notify_reviewer(review, mailer):
    message = f"Review {review.title} is ready"
    mailer.send(
        to=review.reviewer_email,
        subject="Review requested",
        body=message,
    )

Bad Code

notifications.py
from app.email import send_email


def notify_reviewer(review):
    send_email(
        review.reviewer_email,
        "Review requested",
        f"Review {review.title} is ready",
    )

Review Notes

What to review

Good Code

The good version makes the mailer dependency explicit, so tests can pass a fake mailer and assert behavior.

Bad Code

The bad version imports a global side-effect function directly. Tests must patch the import path correctly, and production coupling stays hidden.

Takeaways

  • Injected dependencies make side effects explicit and keep tests focused on behavior.