Forum: RSpec Rspec with ActionMailer and .deliver

60325dab946357c9c052e12a94835a5b?d=identicon&s=25 Todd Sedano (professor)
on 2011-07-27 19:13
(Received via mailing list)
I'm in the process of migrating from Rails 2 with rspec 1 to Rails 3
with
rspec 2, the process has been going pretty well, however, today I came
across an issue that I wanted to share.

I have a controller that sends out an email through a mailer.

Rails 2
code:
CurriculumCommentMailer.deliver_comment_update(@curriculum_comment,
"created")
Rails 3 code:
CurriculumCommentMailer.comment_update(@curriculum_comment,
"created").deliver

 In my controller spec, I test to see if the email was sent out.

Rspec 1
        it "emails the comment" do
          CurriculumCommentMailer.should_receive(:deliver_comment_update)
          post :create, :curriculum_comment =>
@curriculum_comment.attributes
        end

Rspec 2
In my opinion, I expected the following code to work
        it "emails the comment" do
          CurriculumCommentMailer.should_receive(:comment_update)
          post :create, :curriculum_comment =>
@curriculum_comment.attributes
        end

However it does not. Since I'm calling should_receive on an object that
isn't a stub/mock/double, I expected should_receive to call the
underlying
code, it does not so .deliver is called on a NilClass. (undefined method
`deliver' for nil:NilClass)


The following code does work
          mailer = double("mailer")
          mailer.stub(:deliver)

 CurriculumCommentMailer.should_receive(:comment_update).and_return(mailer)

Whereas I expected this code to work, but it does not either

 CurriculumCommentMailer.should_receive(:comment_update).and_return(double("mailer").stub(:deliver))


thanks for your advice,

Todd
38a91d5029a6e2a12ec7a083234bd7db?d=identicon&s=25 Chris M. (chris_m)
on 2011-08-03 19:26
(Received via mailing list)
On 27 July 2011 18:09, Todd Sedano <todd.sedano@sv.cmu.edu> wrote:

>     post :create, :curriculum_comment =>
> isn't a stub/mock/double, I expected should_receive to call the underlying
> code, it does not so .deliver is called on a NilClass.(undefined method
> `deliver' for nil:NilClass)

You're right -- #should_receive stubs out the object's underlying
code, so it never gets called.

> The following code does work
>     mailer = double("mailer")
>     mailer.stub(:deliver)
>
> CurriculumCommentMailer.should_receive(:comment_update).and_return(mailer)
> Whereas I expected this code to work, but it does not either
>
>
CurriculumCommentMailer.should_receive(:comment_update).and_return(double("mailer").stub(:deliver))

That's odd -- I would expect that second version to work if the first
version is working. What error did you get? Was it the same "undefined
method `deliver' for nil:NilClass" as before?

Chris
7f57fa27aee305fa7ee2d48004d43f73?d=identicon&s=25 Jason R. (jason_r)
on 2011-08-16 18:30
Chris M. wrote in post #1014770:
>CurriculumCommentMailer.should_receive(:comment_update).and_return(double("mailer").stub(:deliver))
>
> That's odd -- I would expect that second version to work if the first
> version is working. What error did you get? Was it the same "undefined
> method `deliver' for nil:NilClass" as before?

It was giving this error:
NoMethodError: undefined method `deliver' for
#<RSpec::Mocks::MessageExpectation:0x10542bb88>

But, I changed the test to this and it works fine:
CurriculumCommentMailer.should_receive(:comment_update).and_return(double("mailer",
:deliver => true))

-Jason
38a91d5029a6e2a12ec7a083234bd7db?d=identicon&s=25 Chris M. (chris_m)
on 2011-08-17 00:19
(Received via mailing list)
On 16 Aug 2011, at 17:30, Jason R. wrote:

>
> But, I changed the test to this and it works fine:
>
CurriculumCommentMailer.should_receive(:comment_update).and_return(double("mailer",
> :deliver => true))

Ah, of course! Because #stub doesn't return the object whose method
you're stubbing, it returns a message expectation. I should have spotted
that

Chris
This topic is locked and can not be replied to.