在使用Rails 3
的测试模式下发送邮件时,我遇到了一个奇怪的问题似乎我的邮寄者没有退回任何东西。例如,我有一个名为UserMailer的邮件程序。用户可以在应用程序中进行需要批准的更改,这样就会有一个名为changes_approved的方法,该方法应该向用户发送一封电子邮件,通知他们他们的更改已被批准..class
UserMailer < ActionMailer::Base
default :from => "from@example.com"
def changes_approved(user, page)
@user = user
@page = page
mail(:to => user.email, :subject => "Your changes have been approved")
end
end
在我的控制器中,我有以下一行
UserMailer.changes_approved(@page_revision.created_by, @page_revision.page).deliver
然而,此时我的测试失败并出现错误:
未定义的方法`deliver'代表nil:NilClass
当我在开发网站上触发相同的操作(http:// localhost:3000通过浏览器)时,电子邮件会被正确发送出去,一切都很愉快
为了进一步增加混淆,我正在使用设计进行身份验证,而且电子邮件似乎在测试和开发模式下都能正常工作。当然,我没有得到同样的错误,根据我的电子邮件规范测试,每个人都在工作
所以这让我相信我的邮件有问题,而不是我的测试邮件配置本身,但我不知道是什么。任何建议将不胜感激
由于
答案 0 :(得分:10)
我使用了https://gist.github.com/1031144 转换
# Rails 2 method:
UserMailer.should_receive(:deliver_signup)
到
# Cumbersome Rails 3 method:
mailer = mock
mailer.should_receive(:deliver)
UserMailer.should_receive(:signup).and_return(mailer)
答案 1 :(得分:5)
我遇到了类似的问题 - 可能是UserMailer.changes_approved方法被替换为模拟方法,该方法返回nil(我没有使用shoulda进行该测试,但这是我最好的猜测)。
我的代码看起来像这样(修改为使用您的示例):
UserMailer.expects(:changes_approved).once
我用额外的存根修复了它:
@mailer = stub(:deliver)
UserMailer.expects(:changes_approved).once.returns(@mailer)
nil现在被@mailer取代。
答案 2 :(得分:2)
要测试延迟的动作邮件程序,我们需要先将delayed_job的配置(在config / initializers / delayed_job_config.rb中)更改为
Delayed::Worker.delay_jobs = !Rails.env.test?
并且在您的测试中,期望值应设置为
mock_mail = mock(:mail)
mock_mail.should_receive(:deliver)
UserMailer.should_receive(:changes_approved).with(user, page).and_return(mock_mail)
答案 3 :(得分:1)
我找到了答案,
看起来问题出在我测试这些邮件的方式上。在每个控制器测试中,我都有类似于
的行UserMailer.should_receive(:changes_approved).with(user, page)
虽然这个测试通过很好,但似乎打破了邮件本身。我从测试中删除了这一行,现在他们通过了确定。对ActionMailer :: Base.deliveries.last的后续测试检查发送的电子邮件的详细信息是正确的,所以我很高兴这条线不是必需的。
如果有人解释为什么会破坏这个,我会有兴趣找出
非常感谢