将所有外发电子邮件重定向到单个地址以进行测试

时间:2010-12-08 23:01:06

标签: ruby-on-rails email testing environment actionmailer

在Ruby on Rails中,我遇到的情况是我希望我的应用程序(在特定的测试环境中)拦截应用程序生成的所有外发电子邮件,而是将它们发送到不同的测试地址(也许修改身体说“最初发送到:......”。)。

我看到ActionMailer有一些钩子来观察或拦截邮件,但如果有更简单的方法,我不想自己动手解决。建议?

4 个答案:

答案 0 :(得分:11)

我们正在使用sanitize_email gem取得了巨大成功。它会将所有电子邮件发送到您指定的地址,并将主题与原始收件人一起预先添加。听起来它完全符合您的要求,并使QA-ing电子邮件变得轻而易举。

答案 1 :(得分:1)

通常,您在测试中执行的操作是检查ActionMailer :: Base.deliveries,它是通过您的应用程序发送的邮件的TMail对象数组。在测试环境中,默认设置是没有任何内容被传递,只是放入该数组。

我还会考虑在您的测试中使用email_spec。比滚动自己的测试功能更方便。在使用email_spec,capybara的辅助函数和web步骤以及factory_girl之间,这几乎接近应用程序表面区域的80%,用于在我的大多数应用程序中进行测试。

答案 2 :(得分:1)

老问题,但首先打击谷歌...

我最终通过(ab)使用delivery_method = :sendmail以不同的方式解决了这个问题,这有效地将电子邮件发送到可执行文件;假设这是sendmail,但它可以是任何东西,真的。

config/environments/development.rb中,您可以执行以下操作:

YourApp::Application.configure do
    # [...]
    config.action_mailer.delivery_method = :sendmail
    config.action_mailer.sendmail_settings = {
        location: "#{Rails.root}/script/fake-sendmail",
        arguments: 'martin+rails@arp242.net',
    }
end

然后制作script/fake-sendmail

#!/bin/sh
sendmail -if fake_sendmail@example.com "$1" < /dev/stdin

(别忘了制作这个可执行文件!)

相关解决方案(我更喜欢)是将其附加到mbox文件中;这需要很少的设置。

config/environments/development.rb看起来很相似:

YourApp::Application.configure do
    # [...]
    config.action_mailer.delivery_method = :sendmail
    config.action_mailer.sendmail_settings = {
        location: "#{Rails.root}/script/fake-sendmail",
        arguments: "'#{Rails.root}/tmp/mail.mbox'",
    }
end

script/fake-sendmail现在看起来像:

#!/bin/sh
echo "From FAKE-SENDMAIL $(date)" >> "$1"
cat /dev/stdin >> "$1"
echo >> "$1"

使用$any电子邮件客户端...

打开mbox文件

这是一种非常简单的方法,似乎效果很好。更多细节can be found here(我是本页的作者)。

答案 3 :(得分:1)

Rails 3.0.9 +

现在使用Action Mailer interceptors非常简单。

拦截器使更改外发邮件的接收地址,主题和其他详细信息变得容易。只需定义您的拦截器,然后将其注册到*str文件中即可。

lib / sandbox_mail_interceptor.rb

init

config / init / mailers.rb

# Catches outgoing mail and redirects it to a safe email address.
module SandboxMailInterceptor

  def self.delivering_email( message )
    message.subject = "Initially sent to #{message.to}: #{message.subject}"
    message.to = [ ENV[ 'SANDBOX_EMAIL' ] ]
  end
end

例如,如果您需要在不受拦截者干扰的情况下测试原始电子邮件,也可以随时取消注册拦截器。

require Rails.root.join( 'lib', 'sandbox_mail_interceptor' )

if [ 'development', 'staging' ].include?( Rails.env )
  ActionMailer::Base.register_interceptor( SandboxMailInterceptor )
end