12

Currently when I have a delayed method in my code like the following:

CommentMailer.delay.deliver_comments(@comment, true)

I write something like this in my spec:

dj = mock("DelayProxy")
CommentMailer.should_receive(:delay).and_return(dj)
dj.should_receive(:deliver_comments).with(comment, true)

Is there a better way to handle this and/or chained methods like that in rSpec in general?

Jared
  • 2,885
  • 2
  • 28
  • 31

3 Answers3

27

We can just have one more line in the before block as following:

CommentMailer.stub(:delay).and_return(CommentMailer)

Then you then can have the normal mock check as following:

CommentMailer.should_receive(:deliver_comments).with(comment, true)
Anh Nguyen
  • 1,202
  • 14
  • 17
  • Using `stub` from rspec-mocks' old `:should` syntax without explicitly enabling the syntax is deprecated in rspec-3. This seems to work `expect(CommentMailer).to receive(:delay).and_return(CommentMailer)`. If you dont want to explicitly test it, you could use `allow` instead of `expect`. – Pete Jan 29 '16 at 19:09
2

Here are some discussions about chaining methods in rSpec that I found helpful:

Stubbing Chained Methods with Rspec

http://groups.google.com/group/rspec/browse_thread/thread/6b8394836d2390b0#

Community
  • 1
  • 1
Jared
  • 2,885
  • 2
  • 28
  • 31
1
describe '#perform' do
    subject do
      Delayed::Worker.delay_jobs = false
      proc { worker.perform() }
    end

    it { is_expected.to change { ActionMailer::Base.deliveries.length }.by(2) }
  end

Set delayed job as false and u can test it like simple