李哲 — MAY 26, 2015
原文链接:Testing async emails, the Rails 4.2+ way
假设想写一个需要发送邮件的应用,我们都知道在这种情况是绝对不能block控制器的,因此异步传送才是解决之道。为了达到这个目的,我们需要 将邮件发送代码从最初的request/response
循环中移到后台的异步处理进程中去。
然而,做出这样的改变之后,我们如何确保代码能够一如往常的运行呢?在这篇博文中,我们会探索一种新方法来进行测试,我们将要使用的MiniTest(Rails
已经内置了这个框架), 这里的概念同样使用Rspec
。
现在有一个好消息,那就是从Rails 4.2
开始,异步传送邮件已经比之前简单多了。我们在例子中使用Sidekiq
作为队列系统。由于ActionMailer#deliver_later
建立在ActiveJob
之上, 接口非常的简洁明了。这表示,要不是我刚才提了一下,身为开发者或用户的你也不会知情。建立队列系统是另外一个话题, 你可以在getting started with Active Job here中了解更多相关的信息。
别太依赖小组件
在例子中,我们假定Sidekiq
及其依赖组件配置正确,因此本场景特有的一段代码是声明Active Job
该使用哪一个队列调节器。
# config/application.rb
module OurApp
class Application < Rails::Application
# ...
config.active_job.queue_adapter = :sidekiq
end
end
Active Job
在隐藏实质性的队列配置细节方面功能非常强大,以至于若是使用Resque
,Delayed Job
或其他组件,代码也不需要太大的改动。 因此,如果我们转而使用Sucker Punch
,唯一的改变就是在引用相应的依赖包后,将queue_adapter
从:sidekiq
改为:sucker_punch
就可以了。
站在Active Job的肩膀上
如果你是Rails 4.2
或者Active Job
不太了解,https://blog.engineyard.com/2014/getting-started-with-active-job 是就是很好的入门读物。然而,这篇文章留给我的一个小期许是,找到一种简洁、地道的测试方法,从而让所有组件都能正常的运行。
根据本文的目标,我们假定你已经部署了:
- Rails 4.2或者一个更高的版本
- 已经设置好
queue_adapter
的Active Job (Sidekiq, Resque, 等)- 一封邮件
任何邮件都应该能够按照这里描述的方式正常工作,这里我们就用一封欢迎邮件来使这个例子更实用: