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
On 27 July 2011 18:09, Todd S. [email protected] 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
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
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