ruby-on-rails - Rspec:ActionMailer::Base.deliveries 总是空的

标签 ruby-on-rails rspec

我写了一个 RSpec 集成测试。根据 test.log,我可以看到它已经发送了一封电子邮件,但是当我尝试使用 ActionMailer::Base.deliveries 访问该电子邮件时,它总是显示它是空的。

我已经阅读了其他类似的问题并尝试了一切。我难住了。

这是使用 Capybara/RSpec 的代码:

it "should notify owner" do

  puts "Delivery method: #{ActionMailer::Base.delivery_method.inspect}"
  # This returns: ":test", which is correct

  # Get other guests to do the review
  @review = Review.last
  share_link = "http://#{@account.subdomain}.cozimo.local:#{Capybara.server_port}/review/#{@review.slug}"

  visit(share_link)

  fill_in "email", :with => @user1.email
  fill_in "password", :with => "foobar"

  click_button "Start Review"

  # Add a comment
  click_on "ice-global-note-button"
  find(:css, "#ice-global-note-panel > textarea.ui-corner-all").set "Foo"
  click_on "ice-global-note-submit-button"

  # Test is failing here. WTF? The array should not be empty
  ActionMailer::Base.deliveries.empty?.should be_false

  # Check that a notification email was sent to the owner
  open_email(@owner.email)
  current_email.should have_content "Hi #{@owner.first_name}"

end

正如你在上面看到的, config.action_mailer.delivery_method = :test

在test.log中,显示邮件确实发送了!
Sent mail to somebody1@example.com (62ms)
Date: Tue, 29 Jan 2013 13:53:48 -0500
From: Review Studio <support@cozimo.com>
To: somebody1@example.com
Message-ID: <51081abcd9fbf_5bd23fef87b264a08066@Leonards-MacBook-Pro.local.mail>
Subject: Notes added for Test
Mime-Version: 1.0
Content-Type: text/plain;
 charset=UTF-8
Content-Transfer-Encoding: 7bit

Hi Bruce,

Just letting you know that you have new notes added to the review:

  Project: Test
  Description: Test description
  URL: http://ballistiq.cozimo.local:3000/review/625682740

Thanks,

Review Studio
Completed 200 OK in 170ms (Views: 0.2ms | ActiveRecord: 4.3ms)

最佳答案

这是一个使用 Capybara 和 Selenium 的集成测试。因此,您必须等待 应用程序在检查它是否已发送邮件之前实际发送邮件。

注意 - 这解决了问题,但通常是不好的做法

添加 sleep 1告诉 rspec 在触发发送邮件事件后等待。然后它通过检查 ActionMailer::Base.deliveries 数组来恢复并通过。

如前所述,这通常是不好的做法,因为它会减慢测试速度。

更好的方法

集成测试根本不应该测试发送的邮件。测试应该被划分为被测试类的明确职责。因此,我们会以不同的方式构建测试,以便我们只测试在另一个类( Controller 或资源测试)中发送的邮件。我们还可以使用期望来检查对邮件方法的调用是否确实进行了,尽管我们可能仍然会遇到计时问题。

关于ruby-on-rails - Rspec:ActionMailer::Base.deliveries 总是空的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14590242/

相关文章:

ruby - Capybara-webkit、rspec 集成规范和 xvfb : webkit_server: Fatal IO error: client killed

ruby-on-rails-3 - Rails 3.0.9 + Devise + Cucumber + Capybara 臭名昭著的 "No route matches/users/sign_out"

ruby-on-rails - 测试 Controller 时禁用渲染

ruby-on-rails - 我可以使用相同的 s3 存储桶进行暂存和生产吗?

ruby-on-rails - 如果空闲,Rails Protect_from_forgery 会破坏登录表单

ruby-on-rails - 如何使用 Ruby 中哈希的查询参数构造 URI

ruby-on-rails - 测试设计 - Capybara::ElementNotFound:无法找到 xpath "/html"

ruby - 根据要求使用特定的 VCR 磁带

html - 如何将我的前端开发人员构建的 HTML 页面添加到 Rails 元素中?

ruby-on-rails - Rails 中的通知系统