Ruby on Rails Thursday, December 1, 2011

http://stackoverflow.com/questions/8339957/actionmailer-test-failed-but-works-in-development-environment

The ActionMailer in my Rails 3.1 project has an odd behavior, the ActionMailer::Base.deliveries is empty in test while I can actually receive the email by running the code in rails console. Anybody can points out what wrong it is?

# spec/mailers/user_mailer_spec.rb
require "spec_helper"

describe
UserMailer do
  describe
".reminding_email" do
    subject
{ UserMailer.reminding_email(user).deliver }
    let
(:user) { create :confirmed_user_with_mass_tasks }
    it
"should be delivered" do
     
ActionMailer::Base.deliveries.should_not be_empty
   
end
    its
(:to) { should == [user.email] }
    its
(:subject) { should == "Task Reminding" }
 
end
end

# app/mailers/user_mailer.rb
class UserMailer < ActionMailer::Base
  layout
"email"
 
default from: Rails.env.production? ? "<production>@gmail.com" : "<test>@gmail.com"
 
def reminding_email(user)
   
@tasks = user.tasks.reminding_required
   
@current = Time.current
    mail
(to: user.email, subject: "Task Reminding")
 
end
end

Failures:

1) UserMailer.reminding_email should be delivered Failure/Error: ActionMailer::Base.deliveries.should_not be_empty expected empty? to return false, got true # ./spec/mailers/user_mailer_spec.rb:8:in `block (3 levels) in '

Finished in 11.81 seconds 42 examples, 1 failure, 2 pending

# config/environments/test.rb
RemindersForMe::Application.configure do
 
# Settings specified here will take precedence over those in config/application.rb

 
# The test environment is used exclusively to run your application's
 
# test suite.  You never need to work with it otherwise.  Remember that
 
# your test database is "scratch space" for the test suite and is wiped
 
# and recreated between test runs.  Don't rely on the data there!
  config
.cache_classes = true

 
# Configure static asset server for tests with Cache-Control for performance
  config
.serve_static_assets = true
  config
.static_cache_control = "public, max-age=3600"

 
# Log error messages when you accidentally call methods on nil
  config
.whiny_nils = true

 
# Show full error reports and disable caching
  config
.consider_all_requests_local       = true
  config
.action_controller.perform_caching = false

 
# Raise exceptions instead of rendering exception templates
  config
.action_dispatch.show_exceptions = false

 
# Disable request forgery protection in test environment
  config
.action_controller.allow_forgery_protection    = false

 
# Tell Action Mailer not to deliver emails to the real world.
 
# The :test delivery method accumulates sent emails in the
 
# ActionMailer::Base.deliveries array.
  config
.action_mailer.delivery_method = :test

 
# Use SQL instead of Active Record's schema dumper when creating the test database.
 
# This is necessary if your schema can't be completely dumped by the schema dumper,
 
# like if you have constraints or database-specific column types
 
# config.active_record.schema_format = :sql

 
# Print deprecation notices to the stderr
  config
.active_support.deprecation = :stderr

 
# Setup default URL options as devise needed
  config
.action_mailer.default_url_options = { :host => 'localhost:3000' }
end

Application:

# config/application.rb
require File.expand_path('../boot', __FILE__)

# Pick the frameworks you want:
require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
require "active_resource/railtie"
require "sprockets/railtie"
# require "rails/test_unit/railtie"

if defined?(Bundler)
 
# If you precompile assets before deploying to production, use this line
 
# Bundler.require(*Rails.groups(:assets => %w(development test)))
 
Bundler.require *Rails.groups(:assets) if defined?(Bundler)
 
# If you want your assets lazily compiled in production, use this line
 
# Bundler.require(:default, :assets, Rails.env)
end

module RemindersForMe
 
class Application < Rails::Application
   
# Settings in config/environments/* take precedence over those specified here.
   
# Application configuration should go into files in config/initializers
   
# -- all .rb files in that directory are automatically loaded.

   
# Custom directories with classes and modules you want to be autoloadable.
   
# config.autoload_paths += %W(#{config.root}/extras)

   
# Only load the plugins named here, in the order given (default is alphabetical).
   
# :all can be used as a placeholder for all plugins not explicitly named.
   
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]

   
# Activate observers that should always be running.
   
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer

   
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
   
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
   
# config.time_zone = 'Central Time (US & Canada)'

   
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
   
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
   
# config.i18n.default_locale = :de

   
# Configure the default encoding used in templates for Ruby 1.9.
    config
.encoding = "utf-8"

   
# Configure sensitive parameters which will be filtered from the log file.
    config
.filter_parameters += [:password]

   
# Enable the asset pipeline
    config
.assets.enabled = true

   
# Version of your assets, change this if you want to expire all your assets
    config
.assets.version = '1.0'

   
# Set Rspec generator as default
    config
.generators do |g|
      g
.test_framework :rspec
   
end

   
# Set Mailer of Devise
    config
.to_prepare do
     
Devise::Mailer.layout "email"
   
end
 
end
end


Best regards,
Zhi-Qiang Lei

No comments:

Post a Comment