测试邮件时,ActionMailer失败

时间:2014-10-10 14:48:15

标签: ruby-on-rails ruby rspec actionmailer

Rails 4.1.4和Rspec 3

我正在使用Rspec进行非常基本的电子邮件测试。如果我从rails控制台调用邮件程序,它可以正常工作。如果我从邮件程序规范中调用它,我会得到:

wrong number of arguments (0 for 1..2)

邮件是非常基本的:

  def create_team_invite(org, email)
    @organization = org
    mail(:to=>email, :subject=>'Test Subject')
  end

测试也很基础:

it 'can send out emails to invite others to create teams' do
  UserMailer.create_team_invite(@org, 'test@test.com').deliver
  expect(ActionMailer::Base.deliveries.count).to eq 1
  mail = ActionMailer::Base.deliveries.first
  expect(mail.subject).to eq 'Test Subject'
  expect(mail.from).to eq 'test@test.com'
end

它在邮件中的“mail(:to ...”行)失败。似乎可能是我的环境中的一些配置问题,但我的测试设置与Dev完全相同,使用SMTP并将其发送到Mailcatcher端口。我发现异常并查看了Backtrace,但没有看到任何异常......

之前有人见过这个吗?

更新:提供所请求的其他信息。

我的test.rb,减去评论:

Rails.application.configure do
  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_dispatch.show_exceptions = false
  config.action_controller.allow_forgery_protection = false
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.perform_deliveries = true
  config.active_support.deprecation = :stderr
  config.action_mailer.default_url_options = { :host => 'lvh.me:3000', :only_path=>false }
end

整个rspec失败是:

UserMailer

团队加入电子邮件     可以发送电子邮件邀请其他人创建团队(FAILED - 1)

故障:

  1) UserMailer Team Joining Email can send out emails to invite others to create teams
     Failure/Error: UserMailer.create_team_invite(@team, 'test@test.com').deliver
     ArgumentError:
       wrong number of arguments (0 for 1..2)
     # ./app/mailers/user_mailer.rb:11:in `create_team_invite'
     # ./spec/mailers/user_mailer_spec.rb:36:in `block (3 levels) in <top (required)>'

Finished in 0.25858 seconds (files took 29 minutes 48 seconds to load)
1 example, 1 failure

我配置电子邮件的方式是通过初始化程序,从我的配置中加载每个环境的email.yml文件。 test和dev使用的完全相同的过程,具有相同的设置。 (再次,我发送给Mailcatcher,而不仅仅是mail_delivery:test)

更新2

我把它缩小到Mailer错过了“请求”对象。如果我挖掘错误发生的位置(AbstractController rendering.rb,第109行),它会尝试引用请求对象:

if defined?(request) && request && request.variant.present?

这是调用Rack test.rb第121行:

  def request(uri, env = {}, &block)
    env = env_for(uri, env)
    process_request(uri, env, &block)
  end

所以它就像Rack Test.rb类被视为抽象控制器中的请求方法......但我不知道在这个特定的项目中是如何发生的,或者为什么发生这种情况......

1 个答案:

答案 0 :(得分:0)

我得到同样的错误,当我只是试图测试邮件程序对象时,它似乎正在尝试调用机架测试请求代码。所以我所做的就是不包括我在specihelper中为邮件规范添加的所有内容。这解决了我的问题。

# require 'spec_helper' -> I removed this line, 
# and manually require the files that's needed to just test the mailer object: 
require 'rubygems'
require './config/environment'
require './app/mailers/your_mailer'

注意:我只是使用action_mailer做一个机架项目,没有rails东西。所以你的解决方案会有所不同,但你明白了。

更新:

做了一些更多的故障排除。我在spec_helper.rb文件中发现了这个问题

RSpec.configure do |config|
  config.include include RackSpecHelper # notice the double include
  ...
end

# where RackSpecHelper is a custom module
module RackSpecHelper
  include Rack::Test::Methods
  # a bunch of other helper methods
end

请注意此行中的双重包含

config.include include RackSpecHelper

起初我尝试删除该行,我的邮件程序测试运行正常。可疑双重包含,我删除包含所以它就像这样

config.include RackSpecHelper

现在我的邮件程序测试运行得很好,而不必像我之前发布的那样进行手动操作(并且它可以与使用机架测试内容的其他测试一起运行)。

双重包含基本上正在做

config.include(include(RackSpecHelper))

包括配置块中的RackSpecHelper,它加载顶级命名空间中的所有方法! (非常糟糕的事)。它有效,但这意味着Rack :: Test :: Methods的所有方法都在全局命名空间中。

所以我猜测你的情况,你可能在spec_helper中有一行,包括像这样的全局命名空间中的Rack :: Test :: Methods

include Rack::Test::Methods

将其删除,然后将其放入RSpec配置中,如此

RSpec.configure do |config|
  config.include RackSpecHelper
end