title: ActionMailer: Test failed but works in development environment
body: <p>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?</p>
  
  <pre><code># 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 &lt; ActionMailer::Base
    layout "email"
    default from: Rails.env.production? ? "&lt;production&gt;@gmail.com" : "&lt;test&gt;@gmail.com"
    def reminding_email(user)
      @tasks = user.tasks.reminding_required
      @current = Time.current
      mail(to: user.email, subject: "Task Reminding")
    end
  end
  </code></pre>
  
  <p>Failures:</p>
  
  <p>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 '</p>
  
  <p>Finished in 11.81 seconds
  42 examples, 1 failure, 2 pending</p>
  
  <pre><code># 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 =&gt; 'localhost:3000' }
  end
  </code></pre>
  
  <p>Application:</p>
  
  <pre><code># 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 =&gt; %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 &lt; 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 &amp; 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
  </code></pre>
  
  <p>Now change the spec as follow:</p>
  
  <pre><code>require "spec_helper"
  
  describe UserMailer do
    describe ".reminding_email" do
      subject { UserMailer.reminding_email(user) }
      let(:user) { create :confirmed_user_with_undue_tasks }
      it { expect { subject.deliver }.to change { ActionMailer::Base.deliveries.length }.by(1) }
      its(:to) { should == [user.email] }
      its(:subject) { should == "Task Reminding" }
    end
  end
  </code></pre>
  
  <p>1) UserMailer.reminding_email 
       Failure/Error: it { expect { subject.deliver }.to change { ActionMailer::Base.deliveries.length }.by(1) }
         result should have been changed by 1, but was changed by 2
       # ./spec/mailers/user_mailer_spec.rb:7:in `block (3 levels) in '</p>