讲到测试邮件发送程序,我们首先要让系统可以发送邮件。我们先来给系统添加发送邮件的功能。
添加邮件发送程序
发送邮件要保证我们有目标邮箱,所以呢,我们的用户要有一个属性:email。
我们在用户注册的时候给他发一封邮件。
首先我们创建一个初始化文件
config/initializers/setup_mail.rb,初始化邮箱相关的信息。
ActionMailer::Base.smtp_settings = {
:address => "smtp.163.com",
:port => 25,
:domain => "163.com",
:user_name => "woaiguanshui2012",
:password => "123456asdf",
:authentication => "plain",
:enable_starttls_auto => true
}
我们使用163的邮箱作为邮件发送服务器,需要我们在上面有一个注册用户,这里我注册一个woaiguanshui201,密码是123456asdf。
创建邮件发送程序
然后用rails g mailer命令创建一个mailer程序。
rails g mailer user_mailer
命令会创建app/mailers/user_mailer.rb文件。
class UserMailer < ActionMailer::Base
default :from => "[email protected]"
end
在里面添加一个方法,用来在用户注册的时候给用户发邮件。
def registration_confirmation(user)
mail(:to => user.email, :subject => "Registered")
end
创建邮件内容模板
邮件的内容也可以通过模板来实现,和controller的action对应有一个view一样。我们的mailer的方法也需要一个view来做模板。
创建app/views/user_mailer/registration_confirmation.text.erb文件,在文件中写入下面的内容。
Thank you for registering!
调用邮件发送程序
上下最后一步了,就是在用户注册成功之后,调用这个mailer程序的registration_confirmation方法,就可以发送我们预定义的模板文件中的内容了。
我们把用户注册的方法修改一下,userscontroller的create方法。
def create
@user = User.new(params[:user])
if @user.save
UserMailer.registration_confirmation(@user).deliver
flash[:notice] = "sign up successfully!"
signin(@user)
redirect_to root_path
else
flash.now[:notice] = "sign up failed!"
render :new
end
UserMailer.registration_confirmation(@user).deliver
上面这一行是我们新加入的,就是发邮件用的。
这时候启动我们的服务rails s,然后注册一个用户,然后看看用户的邮箱,就应该有了一封从woaiguanshui2012@163发来的邮件,标题是Registered,内容是thank you for registering!。
这就说明我们的邮件发送程序正常工作了。
丰富邮件内容模板
我们还可以丰富一下邮件的内容,比如添加用户的信息。修改registration_confirmation.text.erb文件。
Hi, <%= @user.nickname %>
Welcome to come back!
这就需要我们在registration_comfirmation方法中添加一个返回的变量@user。
def registration_confirmation(user)
@user = user
mail(:to => user.email, :subject => "Registered")
end
在模板中使用url的话,比如说edit_user_url(@user.id, :host => "localhost:3000"),这时候就只能使用_url方法,不能使用_path方法,同时还需要指定host。这是因为邮件客户端没有web的上下文环境,不像controller中是有web的上下文环境的,所以不需要指定host。当然,每次指定还是比较麻烦的,你也可以在前面创建的配置文件config/initializers/setup_mail.rb中添加下面的一样。
ActionMailer::Base.default_url_options[:host] = "localhost:3000"
这样就可以省略url中的host参数了。
在邮件中添加附件
@user = user
attachments["rails.png"] = File.read("#{Rails.root}/public/images/rails.png")
mail(:to => "#{user.name} <#{user.email}>", :subject => "Registered")
再次注册用户,然后登录用户的邮箱,就会发现收到了一封带有附件的邮件。
关于邮件发送还有很多,大家在使用和设计的过程中会有更多的体会。比如说我们现在的发送邮件和用户注册是同步处理的,这样的话,大量用户注册,就会严重拖慢系统,甚至拖垮系统。邮件没有必要和用户注册同步处理,可以做成异步的,可以做成独立的job。这时候邮件发送就需要独立出来,可以搞成一个邮件队列,只要在用户注册的时候发送一个邮件消息给邮件队列,由队列负责具体的发送工作就可以了。
测试邮件发送程序
关于邮件测试有下面几个目的
邮件正在被处理,创建或者发送。
邮件的内容是正确的,包括标题,发送人,body等。
在正确的时间发送了正确的邮件。
可以从两个方向来测试邮件,一个是单元测试,一个是功能测试。在单元测试中,我们在一个隔离的环境中运行邮件程序,内容是受控的,然后和模拟数据比较输出的内容。在功能测试中,我们在controller和model中正确的使用邮件发送程序,测试在正确的时间发送了正确的邮件。
<b></b>
默认情况下,测试环境是不能发邮件的。他们只会把邮件加入ActionMailer::Base.deliveries数组,通过判断数组不为空,就可以知道邮件是否发送成功。
测试邮件就是两件事:
测试邮件是否加入队列。
测试邮件内容是否正确。
test/unit/user_mailer_test.rb
require 'test_helper'
class UserMailerTest < ActionMailer::TestCase
include FactoryGirl::Syntax::Methods
def test_registration_confirmation
user = FactoryGirl.create(:user_valid)
mail = UserMailer.registration_confirmation(user).deliver
assert !ActionMailer::Base.deliveries.empty?
assert_equal [user.email], mail.to
上面的测试中,首先测试邮件队列是否不为空,然后测试邮件的目标地址是否正确。
本文转自 virusswb 51CTO博客,原文链接:http://blog.51cto.com/virusswb/1080256,如需转载请自行联系原作者