DEV Community

Vasily Polovnyov
Vasily Polovnyov

Posted on

RSpec: when to use double instead of instance_double

Let me remind you of the difference: instance_double can fail a test if methods are not available in the specified class, double doesn't care about anything.

In my experience double is needed in two cases:
1. Instead of an object that doesn't yet exist in the system. There is no class, so instance_double has nothing to rely on.

2. Instead of something minor with a stable API. For example, for emails:

allow(DeadlineMailer)
  .to receive(:last_deadline_warning)
  .and_return(double(:email, deliver_later: true))
Enter fullscreen mode Exit fullscreen mode

Top comments (2)

Collapse
 
robcodes profile image
RobCodes

Could you explain a little more about the return here?

Later in the test, are you testing that the email has been delivered?

I believe that using a strict return double i.g. instance_double allows you to be more explicit with your return.

Collapse
 
vasily profile image
Vasily Polovnyov

Later in the test, are you testing that the email has been delivered?

Not in this case. If I'd have to test that the email has been delivered, I'd assign it and verify:

last_deadline_warning_email = double(...) # or instance_double

allow(DeadlineMailer)
  .to receive(:last_deadline_warning)
  .and_return(last_deadline_warning_email)

# ...

expect(last_deadling_warning_email).to have_received(:deliver_later)
Enter fullscreen mode Exit fullscreen mode

In this particular case I simply stub emails in order to speed up tests. Consider the following example:

describe "#trigger_deadline_alerts" do
  it "..."
  it "..."
  it "..."
  it "..."
end
Enter fullscreen mode Exit fullscreen mode

Without stub we'd have to render and send deadline email 4 times which could be expensive and time consuming.