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:
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:
In spec/models/mailers/some_mailer_spec.rb we would write something like:
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!
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
Русский
English
I’m just learning rspec and despite the now old syntax it was still very helpful. Big thanks!