In Ruby on Rails we are using routes to generate any sort of links. So let’s include routing mechanism into our own script or class.
First, you need to ensure that Rails core is loaded (if you haven’t done this earlier; for example, in script/console you should not do this). I’m assuming you’re creating a script under /script folder:
1 2 3 | ENV['RAILS_ENV'] ||= 'production' require File.dirname(__FILE__) + '/../config/boot' require RAILS_ROOT + '/config/environment' |
Now you need to include ActionController::UrlWriter
module, which allows to write URLs from arbitrary places in your codebase, and configure default_url_options[:host]
:
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # this is slow because all routes and resources being calculated now include ActionController::UrlWriter default_url_options[:host] = 'www.example.com' # map.connect ':controller/:action/:id' url_for(:controller => 'folders', :action => 'show', :id => Folder.first) # => "http://www.example.com/folders/2" # map.resources :folders folders_url # => "http://www.example.com/folders" folder_url(Folder.first) # => "http://www.example.com/folders/2" edit_folder_url(Folder.first) # => "http://www.example.com/folders/2/edit" # you can use relative paths too folders_path # => "/folders" |
Easy and helpful technique. Enjoy!
The post Memo #6: Using named routes and url_for outside the controller in Ruby on Rails first appeared on Dmytro Shteflyuk's Home.]]>
For the beginning we would define helper for reading fixtures and put them into the spec/mailer_spec_helper.rb file:
1 2 3 4 5 6 7 8 9 | 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:
1 | Hello, Bob |
In spec/models/mailers/some_mailer_spec.rb we would write something like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | 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 = '[email protected]' @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!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | context 'Given an signup action of UserController' do controller_name 'user' setup do @user = mock('user') @valid_user_params = { :email => '[email protected]' } 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 |