在Ruby on Rails中,我遇到的情况是我希望我的应用程序(在特定的测试环境中)拦截应用程序生成的所有外发电子邮件,而是将它们发送到不同的测试地址(也许修改身体说“最初发送到:......”。)。
我看到ActionMailer有一些钩子来观察或拦截邮件,但如果有更简单的方法,我不想自己动手解决。建议?
答案 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
电子邮件客户端...
这是一种非常简单的方法,似乎效果很好。更多细节can be found here(我是本页的作者)。
答案 3 :(得分:1)
现在使用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