Rails控制器不会在ActiveMailer测试中发送电子邮件

时间:2014-07-21 15:05:48

标签: ruby-on-rails email rspec actionmailer

我们有一个发送电子邮件的Rails控制器:

class UsersController
  def invite
    mail = WeeklyReport.weekly_report(current_user).deliver
    flash[:notice] = "Mail sent!"
    redirect_to controller: "partners", action: "index"
  end
end

class WeeklyReport < ActionMailer::Base
  def weekly_report(recipient)
    @data = recipient.data
    mail(:to => "#{recipient.name} <#{recipient.email}>", :subject => "Weekly report")
  end
end

手动测试控制器时,实际上是在发送电子邮件。但控制器测试失败了:

it "should send mail" do
  get :invite

  response.should redirect_to "/partners/index"
  request.flash[:notice].should eql("Mail sent!")

  deliveries.size.should == 1 ### TEST FAILS HERE!

  last_email.subject.should ==  "Weekly report"
  last_email.to[0].should == 'user@email.com'
end

# Failure/Error: deliveries.size.should == 1
#   expected: 1
#        got: 0 (using ==)

我的测试环境配置正确:   config.action_mailer.delivery_method = :test

WeeklyReport测试工作正常:

  it "should send weekly report correctly" do
    @user = FactoryGirl.create_list(:user)
    email = WeeklyReport.weekly_report(@user).deliver
    deliveries.size.should == 1
  end

为什么控制器测试失败?

编辑1: 我注意到电子邮件实际上正在发送(真正的电子邮件),忽略了配置:config.action_mailer.delivery_method =:test - 它可能是什么?

编辑2: 我的test.rb文件:

  config.cache_classes = true
  config.eager_load = false
  config.serve_static_assets  = true
  config.static_cache_control = "public, max-age=3600"
  config.consider_all_requests_local       = true
  config.action_controller.perform_caching = false
  config.action_mailer.default_url_options = { :host => 'dev.mydomain.com' }
  config.action_dispatch.show_exceptions = false
  config.action_controller.allow_forgery_protection = false
  config.active_record.default_timezone = :local
  config.action_mailer.delivery_method = :test
  config.active_support.deprecation = :stderr

1 个答案:

答案 0 :(得分:3)

就像你说的那样,它没有使用你的test设置,那么环境问题就一定存在问题。在加载规范并测试之前尝试显式设置它。

it "should send mail" do
  ::ActionMailer::Base.delivery_method = :test
  get :invite

  response.should redirect_to "/partners/index"
  request.flash[:notice].should eql("Mail sent!")

  ::ActionMailer::Base.deliveries.size.should == 1     
  last_email.subject.should ==  "Weekly report"
  last_email.to[0].should == 'user@email.com'
end