Testing mailers with RSpec

Apr 19
2007 07:42 (Development, RSpec, Ruby on Rails) · Русский (7,450 views)

Unfortunately, RSpec does not provide helpers for testing mailers like TestUnit. But it is easy to add them to your application, and here you could find code snippet for testing mailers.

For the beginning we would define helper for reading fixtures and put them into the spec/mailer_spec_helper.rb file:

require File.dirname(__FILE__) + '/spec_helper.rb'

module MailerSpecHelper
  private

    def read_fixture(action)
      IO.readlines("#{FIXTURES_PATH}/mailers/user_mailer/#{action}")
    end
end

Now we need to create fixtures for mailers in the spec/fixtures/mailers folder, each mailer in the separate subfolder like spec/fixtures/mailers/some_mailer/activation:

Hello, Bob

In spec/models/mailers/some_mailer_spec.rb we would write something like:

require File.dirname(__FILE__) + '/../../mailer_spec_helper.rb'

context 'The SomeMailer mailer' do
  FIXTURES_PATH = File.dirname(__FILE__) + '/../../fixtures'
  CHARSET = 'utf-8'

  fixtures :users

  include MailerSpecHelper
  include ActionMailer::Quoting

  setup do
    # You don't need these lines while you are using create_ instead of deliver_
    #ActionMailer::Base.delivery_method = :test
    #ActionMailer::Base.perform_deliveries = true
    #ActionMailer::Base.deliveries = []

    @expected = TMail::Mail.new
    @expected.set_content_type 'text', 'plain', { 'charset' => CHARSET }
    @expected.mime_version = '1.0'
  end

  specify 'should send activation email' do
    @expected.subject = 'Account activation'
    @expected.body    = read_fixture('activation')
    @expected.from    = 'no-email@example.com'
    @expected.to      = users(:bob).email

    Mailers::UserMailer.create_activation(users(:bob)).encoded.should == @expected.encoded
  end
end

That’s almost all. We are fully confident that emails look as we expected. In controller we don’t need to re-test mailers again, we just need to become convinced of mailer calling!

context 'Given an signup action of UserController' do
  controller_name 'user'

  setup do
    @user = mock('user')
    @valid_user_params = { :email => 'some@example.com' }
  end

  specify 'should deliver activation email to newly created user' do
    User.should_receive(:new).with(@valid_user_params).and_return(@user)
    Mailers::UserMailer.should_receive(:deliver_activation).with(@user)
    post :signup, :user => @valid_user_params
    response.should redirect_to(user_activate_url)
  end
end

One Response to 'Testing mailers with RSpec'

Subscribe to comments with RSS or TrackBack to 'Testing mailers with RSpec'.

1
said on 2008-05-04 at 3.08 am

I’m just learning rspec and despite the now old syntax it was still very helpful. Big thanks!

Post a comment

You can use simple HTML-formatting tags (like <a>, <ul> and others). To format your code sample use <code lang="php">$a = "hello";</code> (allowed languages are ruby, php, yaml, html, csharp, javascript). Also you could use <code>$a = "hello";</code> and its syntax would not be highlighted. If you are not using <code> tag, replace < sign with &lt;.

Submit Comment

 
Copyright © 2005 - 2008, Dmytro Shteflyuk