К сожалению, RSpec не предоставляет хелперы для тестирование мейлеров, вроде тех, что есть в TestUnit. Но добавить их в приложение совсем несложно, и в данной заметке я покажу, как это сделать.
Для начала, нам нужно определить хелпер для чтения фикстур и положить их в файл spec/mailer_spec_helper.rb:
module MailerSpecHelper
private
def read_fixture(action)
IO.readlines("#{FIXTURES_PATH}/mailers/user_mailer/#{action}")
end
end
Теперь нам нужно создать фикстуры для мейлеров в spec/fixtures/mailers, каждый мейлер в отдельном подкаталоге , например spec/fixtures/mailers/some_mailer/activation:
В spec/models/mailers/some_mailer_spec.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
Это почти все. Мы полностью уверены в том, что письма выглядят так, как ожидалось. В контроллере мы не должны повторно тестировать мейлеры, нужно всего лишь убедиться в том, что мейлеры вызываются!
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!