Stub thay thế method thật bằng kết quả giả — kiểm soát đầu ra, không quan tâm có gọi hay không.
Mock là stub + có kỳ vọng rằng method phải được gọi — test sẽ fail nếu không gọi.
ruby
# Stub
allow(UserMailer).to receive(:welcome).and_return(double(deliver_later: nil))
# Mock (expect phải được gọi)
expect(UserMailer).to receive(:welcome)
.with(user)
.once
.and_return(double(deliver_later: nil))Khi nào dùng:
- Stub: cô lập dependency (HTTP call, time, external service) để test nhanh và reliable.
- Mock: verify behavior — "code này CÓ gọi service kia không" (integration point).
Lạm dụng mock làm test brittle (test biết quá nhiều về implementation). Ưu tiên test behavior/output thật khi có thể.