天天看点

Rails测试《十一》添加邮件发送程序及测试邮件发送程序

讲到测试邮件发送程序,我们首先要让系统可以发送邮件。我们先来给系统添加发送邮件的功能。

添加邮件发送程序

发送邮件要保证我们有目标邮箱,所以呢,我们的用户要有一个属性: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 &lt; 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,如需转载请自行联系原作者