Challenge 3: Stubbing a Dependency — Solution # notification_service.rb class NotificationService def initialize(mailer) @mailer = mailer end def notify(message) @mailer.send_email(message) end end # spec/notification_service_spec.rb require_relative "../notification_service" describe NotificationService do it "returns whatever the mailer's send_email returns" do fake_mailer = double("Mailer") allow(fake_mailer).to receive(:send_email).and_return("Email queued") service = NotificationService.new(fake_mailer) expect(service.notify("Hello!")).to eq("Email queued") end it "actually calls send_email on the mailer" do fake_mailer = double("Mailer") expect(fake_mailer).to receive(:send_email).with("Hello!") service = NotificationService.new(fake_mailer) service.notify("Hello!") end end =begin Expected RSpec output: NotificationService returns whatever the mailer's send_email returns actually calls send_email on the mailer 2 examples, 0 failures Notes: - The first example uses allow(fake_mailer).to receive(:send_email) — a stub — purely to give send_email a controlled, predictable return value so notify's own return value can be tested in isolation from any real mailer implementation. - The second example uses expect(fake_mailer).to receive(:send_email) — a mock — which does NOT care what send_email returns; it fails the test specifically if send_email is never called with the right argument at all, verifying the interaction itself rather than a value. - .with("Hello!") on the mock additionally verifies the argument passed to send_email matches exactly what notify was given, not just that some call happened. - Neither test depends on a real Mailer class existing at all — the double stands in for it completely, which is the whole point of isolating NotificationService from its dependency. =end