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

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

Action Mailer in Rails 3是一个不错的视频教程,大家可以参考。

还有就是http://guides.rubyonrails.org/action_mailer_basics.html中更加详细的介绍。

 

添加邮件发送程序

发送邮件要保证我们有目标邮箱,所以呢,我们的用户要有一个属性:email。

还是拿我的blog项目作为练习项目。

我们在用户注册的时候给他发一封邮件。

 

首先我们创建一个初始化文件

config/initializers/setup_mail.rb,初始化邮箱相关的信息。

  1. ActionMailer::Base.smtp_settings = { 
  2.   :address              => "smtp.163.com", 
  3.   :port                 => 25, 
  4.   :domain               => "163.com", 
  5.   :user_name            => "woaiguanshui2012", 
  6.   :password             => "123456asdf", 
  7.   :authentication       => "plain", 
  8.   :enable_starttls_auto => true 

我们使用163的邮箱作为邮件发送服务器,需要我们在上面有一个注册用户,这里我注册一个woaiguanshui201,密码是123456asdf。

 

创建邮件发送程序

然后用rails g mailer命令创建一个mailer程序。

  1. rails g mailer user_mailer 

命令会创建app/mailers/user_mailer.rb文件。

  1. class UserMailer < ActionMailer::Base 
  2.   default :from => "woaiguanshui2012@163.com" 
  3. end 

在里面添加一个方法,用来在用户注册的时候给用户发邮件。

  1. class UserMailer < ActionMailer::Base 
  2.   default :from => "woaiguanshui2012@163.com" 
  3.   def registration_confirmation(user) 
  4.     mail(:to => user.email, :subject => "Registered"
  5.   end 
  6. end 

 

创建邮件内容模板

邮件的内容也可以通过模板来实现,和controller的action对应有一个view一样。我们的mailer的方法也需要一个view来做模板。

创建app/views/user_mailer/registration_confirmation.text.erb文件,在文件中写入下面的内容。

  1. Thank you for registering! 

 

调用邮件发送程序

上下最后一步了,就是在用户注册成功之后,调用这个mailer程序的registration_confirmation方法,就可以发送我们预定义的模板文件中的内容了。

我们把用户注册的方法修改一下,userscontroller的create方法。

  1. def create 
  2.     @user = User.new(params[:user]) 
  3.  
  4.     if @user.save 
  5.       UserMailer.registration_confirmation(@user).deliver 
  6.  
  7.       flash[:notice] = "sign up successfully!" 
  8.       signin(@user) 
  9.       redirect_to root_path 
  10.     else 
  11.       flash.now[:notice] = "sign up failed!" 
  12.       render :new 
  13.     end 
  14.   end 

UserMailer.registration_confirmation(@user).deliver 

上面这一行是我们新加入的,就是发邮件用的。

 

这时候启动我们的服务rails s,然后注册一个用户,然后看看用户的邮箱,就应该有了一封从woaiguanshui2012@163发来的邮件,标题是Registered,内容是thank you for registering!。

这就说明我们的邮件发送程序正常工作了。

 

丰富邮件内容模板

我们还可以丰富一下邮件的内容,比如添加用户的信息。修改registration_confirmation.text.erb文件。

  1. Hi, <%= @user.nickname %> 
  2.  
  3. Thank you for registering! 
  4.  
  5. Welcome to come back! 

这就需要我们在registration_comfirmation方法中添加一个返回的变量@user。

  1. def registration_confirmation(user) 
  2.     @user = user 
  3.    mail(:to => user.email, :subject => "Registered"
  4.  end 

在模板中使用url的话,比如说edit_user_url(@user.id, :host => "localhost:3000"),这时候就只能使用_url方法,不能使用_path方法,同时还需要指定host。这是因为邮件客户端没有web的上下文环境,不像controller中是有web的上下文环境的,所以不需要指定host。当然,每次指定还是比较麻烦的,你也可以在前面创建的配置文件config/initializers/setup_mail.rb中添加下面的一样。

  1. ActionMailer::Base.default_url_options[:host] = "localhost:3000" 

这样就可以省略url中的host参数了。

 

在邮件中添加附件

  1. def registration_confirmation(user) 
  2.   @user = user 
  3.   p_w_uploads["rails.png"] = File.read("#{Rails.root}/public/p_w_picpaths/rails.png"
  4.   mail(:to => "#{user.name} <#{user.email}>":subject => "Registered"
  5. end 

再次注册用户,然后登录用户的邮箱,就会发现收到了一封带有附件的邮件。

关于邮件发送还有很多,大家在使用和设计的过程中会有更多的体会。比如说我们现在的发送邮件和用户注册是同步处理的,这样的话,大量用户注册,就会严重拖慢系统,甚至拖垮系统。邮件没有必要和用户注册同步处理,可以做成异步的,可以做成独立的job。这时候邮件发送就需要独立出来,可以搞成一个邮件队列,只要在用户注册的时候发送一个邮件消息给邮件队列,由队列负责具体的发送工作就可以了。

 

测试邮件发送程序

关于邮件测试有下面几个目的

  • 邮件正在被处理,创建或者发送。
  • 邮件的内容是正确的,包括标题,发送人,body等。
  • 在正确的时间发送了正确的邮件。

 

可以从两个方向来测试邮件,一个是单元测试,一个是功能测试。在单元测试中,我们在一个隔离的环境中运行邮件程序,内容是受控的,然后和模拟数据比较输出的内容。在功能测试中,我们在controller和model中正确的使用邮件发送程序,测试在正确的时间发送了正确的邮件。


默认情况下,测试环境是不能发邮件的。他们只会把邮件加入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 
  •      
  •   end 
  • end 

上面的测试中,首先测试邮件队列是否不为空,然后测试邮件的目标地址是否正确。

 

 

原创文章,作者:carmelaweatherly,如若转载,请注明出处:https://blog.ytso.com/tech/opensource/192037.html

(0)
上一篇 2021年11月14日 22:22
下一篇 2021年11月14日 22:22

相关推荐

发表回复

登录后才能评论