在Rails 3中使用ActionMailer发送测试模式的电子邮件

3

我在使用Rails 3的测试模式发送邮件时遇到了一些奇怪的问题。

看起来我的邮件程序没有返回任何内容。例如,我有一个名为UserMailer的邮件程序。用户可以在应用程序中进行需要批准的更改,因此该程序具有一个名为changes_approved的方法,该方法应该向用户发送电子邮件通知他们的更改已被批准。

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

然而,我的测试在这一点上失败并出现以下错误:
“undefined method `deliver' for nil:NilClass”
当我通过浏览器在开发站点(http://localhost:3000)上触发相同的操作时,电子邮件会正确发送,并且一切都工作得很好。此外,我正在使用Devise进行身份验证,其邮件似乎在测试和开发模式下都能正常工作。毫无疑问,我没有遇到相同的错误,根据我的email-spec测试,一切都正常。
因此,我认为问题出在我的邮件处理程序上,而不是我的测试邮件配置本身,但我不知道具体问题出在哪里。如果您有任何建议,将不胜感激。
谢谢
4个回答

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)

5

我有一个类似的问题 - 可能是 UserMailer.changes_approved 方法被替换为一个返回 nil 的模拟方法(我没有在那个测试中使用 shoulda,但这是我最好的猜测)。

我的代码看起来像这样(修改以使用您的示例):

UserMailer.expects(:changes_approved).once

我通过添加一个额外的存根修复了它:

@mailer = stub(:deliver)
UserMailer.expects(:changes_approved).once.returns(@mailer)

现在,nil已被@mailer取代。

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)

非常好,谢谢。这正是您如何通过使用RSpec + email_spec + Delayed::Job进行测试的方法。使用Workless在本地和Heroku上动态启动所需的工作程序。 - chadoh

1

好的,我已经找到答案了,

看起来问题出在我测试这些邮件发送器的方式上。在每个控制器测试中,我都有一行类似于以下的代码:

UserMailer.should_receive(:changes_approved).with(user, page)

虽然这个测试通过得很好,但它似乎打破了邮件发送本身。我已经从测试中删除了这行代码,现在测试通过了。对 ActionMailer::Base.deliveries.last 的后续测试检查已发送电子邮件的详细信息是否正确看起来是可以的,所以我很高兴这行代码不是必要的。

如果有人能够解释为什么会出现这样的问题,我会很感兴趣

无论如何,谢谢


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接