The `filter_param` matcher is used to test parameter filtering configuration. Specifically, it asserts that the given parameter is present in `config.filter_parameters`.
class MyApplication < Rails::Application config.filter_parameters << :secret_key end # RSpec describe ApplicationController do it { should filter_param(:secret_key) } end # Test::Unit class ApplicationControllerTest < ActionController::TestCase should filter_param(:secret_key) end
@return [FilterParamMatcher]
# File lib/shoulda/matchers/action_controller/filter_param_matcher.rb, line 24 def filter_param(key) FilterParamMatcher.new(key) end
The `permit` matcher tests that an action in your controller receives a whitelist of parameters using Rails’ Strong Parameters feature (specifically that `permit` was called with the correct arguments).
Here’s an example:
class UsersController < ApplicationController def create user = User.create(user_params) # ... end private def user_params params.require(:user).permit( :first_name, :last_name, :email, :password ) end end # RSpec describe UsersController do it do should permit(:first_name, :last_name, :email, :password). for(:create) end end # Test::Unit class UsersControllerTest < ActionController::TestCase should permit(:first_name, :last_name, :email, :password). for(:create) end
If your action requires query parameters in order to work, then you’ll need to supply them:
class UsersController < ApplicationController def update user = User.find(params[:id]) if user.update_attributes(user_params) # ... else # ... end end private def user_params params.require(:user).permit( :first_name, :last_name, :email, :password ) end end # RSpec describe UsersController do before do create(:user, id: 1) end it do should permit(:first_name, :last_name, :email, :password). for(:update, params: { id: 1 }) end end # Test::Unit class UsersControllerTest < ActionController::TestCase setup do create(:user, id: 1) end should permit(:first_name, :last_name, :email, :password). for(:update, params: { id: 1 }) end
Finally, if you have an action that isn’t one of the seven resourceful actions, then you’ll need to provide the HTTP verb that it responds to:
Rails.application.routes.draw do resources :users do member do put :toggle end end end class UsersController < ApplicationController def toggle user = User.find(params[:id]) if user.update_attributes(user_params) # ... else # ... end end private def user_params params.require(:user).permit(:activated) end end # RSpec describe UsersController do before do create(:user, id: 1) end it do should permit(:activated).for(:toggle, params: { id: 1 }, verb: :put ) end end # Test::Unit class UsersControllerTest < ActionController::TestCase setup do create(:user, id: 1) end should permit(:activated).for(:toggle, params: { id: 1 }, verb: :put ) end
@return [StrongParametersMatcher]
# File lib/shoulda/matchers/action_controller/strong_parameters_matcher.rb, line 156 def permit(*params) StrongParametersMatcher.new(params).in_context(self) end
The `redirect_to` matcher tests that an action redirects to a certain location. In a test suite using RSpec, it is very similar to rspec-rails’s `redirect_to` matcher. In a test suite using Test::Unit / Shoulda, it provides a more expressive syntax over `assert_redirected_to`.
class PostsController < ApplicationController def show redirect_to :index end end # RSpec describe PostsController do describe 'GET #show' do before { get :show } it { should redirect_to(posts_path) } it { should redirect_to(action: :index) } end end # Test::Unit class PostsControllerTest < ActionController::TestCase context 'GET #show' do setup { get :show } should redirect_to { posts_path } should redirect_to(action: :index) end end
@return [RedirectToMatcher]
# File lib/shoulda/matchers/action_controller/redirect_to_matcher.rb, line 38 def redirect_to(url_or_description, &block) RedirectToMatcher.new(url_or_description, self, &block) end
The `render_template` matcher tests that an action renders a template or partial. In RSpec, it is very similar to rspec-rails’s `render_template` matcher. In Test::Unit, it provides a more expressive syntax over `assert_template`.
class PostsController < ApplicationController def show end end # app/views/posts/show.html.erb <%= render 'sidebar' %> # RSpec describe PostsController do describe 'GET #show' do before { get :show } it { should render_template('show') } it { should render_template(partial: 'sidebar') } end end # Test::Unit class PostsControllerTest < ActionController::TestCase context 'GET #show' do setup { get :show } should render_template('show') should render_template(partial: 'sidebar') end end
@return [RenderTemplateMatcher]
# File lib/shoulda/matchers/action_controller/render_template_matcher.rb, line 41 def render_template(options = {}, message = nil) RenderTemplateMatcher.new(options, message, self) end
The `render_with_layout` matcher asserts that an action is rendered with a particular layout.
class PostsController < ApplicationController def show render layout: 'posts' end end # RSpec describe PostsController do describe 'GET #show' do before { get :show } it { should render_with_layout('posts') } end end # Test::Unit class PostsControllerTest < ActionController::TestCase context 'GET #show' do setup { get :show } should render_with_layout('posts') end end
It can also be used to assert that the action is not rendered with a layout at all:
class PostsController < ApplicationController def sidebar render layout: false end end # RSpec describe PostsController do describe 'GET #sidebar' do before { get :sidebar } it { should_not render_with_layout } end end # Test::Unit class PostsControllerTest < ActionController::TestCase context 'GET #sidebar' do setup { get :sidebar } should_not render_with_layout end end
@return [RenderWithLayoutMatcher]
# File lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb, line 60 def render_with_layout(expected_layout = nil) RenderWithLayoutMatcher.new(expected_layout).in_context(self) end
The `rescue_from` matcher tests usage of the `rescue_from` macro. It asserts that an exception and method are present in the list of exception handlers, and that the handler method exists.
class ApplicationController < ActionController::Base rescue_from ActiveRecord::RecordNotFound, with: :handle_not_found private def handle_not_found # ... end end # RSpec describe ApplicationController do it do should rescue_from(ActiveRecord::RecordNotFound). with(:handle_not_found) end end # Test::Unit class ApplicationControllerTest < ActionController::TestCase should rescue_from(ActiveRecord::RecordNotFound). with(:handle_not_found) end
@return [RescueFromMatcher]
# File lib/shoulda/matchers/action_controller/rescue_from_matcher.rb, line 34 def rescue_from(exception) RescueFromMatcher.new exception end
The `respond_with` matcher tests that an action responds with a certain status code.
You can specify that the status should be a number:
class PostsController < ApplicationController def index render status: 403 end end # RSpec describe PostsController do describe 'GET #index' do before { get :index } it { should respond_with(403) } end end # Test::Unit class PostsControllerTest < ActionController::TestCase context 'GET #index' do setup { get :index } should respond_with(403) end end
You can specify that the status should be within a range of numbers:
class PostsController < ApplicationController def destroy render status: 508 end end # RSpec describe PostsController do describe 'DELETE #destroy' do before { delete :destroy } it { should respond_with(500..600) } end end # Test::Unit class PostsControllerTest < ActionController::TestCase context 'DELETE #destroy' do setup { delete :destroy } should respond_with(500..600) end end
Finally, you can specify that the status should be a symbol:
class PostsController < ApplicationController def show render status: :locked end end # RSpec describe PostsController do describe 'GET #show' do before { get :show } it { should respond_with(:locked) } end end # Test::Unit class PostsControllerTest < ActionController::TestCase context 'GET #show' do setup { get :show } should respond_with(:locked) end end
@return [RespondWithMatcher]
# File lib/shoulda/matchers/action_controller/respond_with_matcher.rb, line 87 def respond_with(status) RespondWithMatcher.new(status) end
The `route` matcher tests that a route resolves to a controller, action, and params; and that the controller, action, and params generates the same route. For an RSpec suite, this is like using a combination of `route_to` and `be_routable`. For a Test::Unit suite, it provides a more expressive syntax over `assert_routing`.
You can use this matcher either in a controller test case or in a routing test case. For instance, given these routes:
My::Application.routes.draw do get '/posts', controller: 'posts', action: 'index' get '/posts/:id' => 'posts#show' end
You could choose to write tests for these routes alongside other tests for PostsController:
class PostsController < ApplicationController # ... end # RSpec describe PostsController do it { should route(:get, '/posts').to(action: :index) } it { should route(:get, '/posts/1').to(action: :show, id: 1) } end # Test::Unit class PostsControllerTest < ActionController::TestCase should route(:get, '/posts').to(action: 'index') should route(:get, '/posts/1').to(action: :show, id: 1) end
Or you could place the tests along with other route tests:
# RSpec describe 'Routing' do it do should route(:get, '/posts'). to(controller: :posts, action: :index) end it do should route(:get, '/posts/1'). to('posts#show', id: 1) end end # Test::Unit class RoutesTest < ActionController::IntegrationTest should route(:get, '/posts'). to(controller: :posts, action: :index) should route(:get, '/posts/1'). to('posts#show', id: 1) end
Notice that in the former case, as we are inside of a test case for PostsController, we do not have to specify that the routes resolve to this controller. In the latter case we specify this using the `controller` key passed to the `to` qualifier.
#### Qualifiers
##### to
Use `to` to specify the action (along with the controller, if needed) that the route resolves to.
# Three ways of saying the same thing (using the example above) route(:get, '/posts').to(action: index) route(:get, '/posts').to(controller: :posts, action: index) route(:get, '/posts').to('posts#index')
If there are parameters in your route, then specify those too:
route(:get, '/posts/1').to('posts#show', id: 1)
@return [RouteMatcher]
# File lib/shoulda/matchers/action_controller/route_matcher.rb, line 84 def route(method, path) RouteMatcher.new(method, path, self) end
The `set_session` matcher is used to make assertions about the `session` hash.
class PostsController < ApplicationController def show session[:foo] = 'bar' end end # RSpec describe PostsController do describe 'GET #show' do before { get :show } it { should set_session(:foo) } it { should_not set_session(:baz) } end end # Test::Unit class PostsControllerTest < ActionController::TestCase context 'GET #show' do setup { get :show } should set_session(:foo) should_not set_session(:baz) end end
#### Qualifiers
##### to
Use `to` to assert that the key in the session hash was set to a particular value.
class PostsController < ApplicationController def show session[:foo] = 'bar' end end # RSpec describe PostsController do describe 'GET #show' do before { get :show } it { should set_session(:foo).to('bar') } it { should_not set_session(:foo).to('something else') } end end # Test::Unit class PostsControllerTest < ActionController::TestCase context 'GET #show' do setup { get :show } should set_session(:foo).to('bar') should_not set_session(:foo).to('something else') end end
@return [SetSessionMatcher]
# File lib/shoulda/matchers/action_controller/set_session_matcher.rb, line 68 def set_session(key) SetSessionMatcher.new(key) end
The `set_the_flash` matcher is used to make assertions about the `flash` hash.
class PostsController < ApplicationController def index flash[:foo] = 'A candy bar' end def destroy end end # RSpec describe PostsController do describe 'GET #index' do before { get :index } it { should set_the_flash } end describe 'DELETE #destroy' do before { delete :destroy } it { should_not set_the_flash } end end # Test::Unit class PostsControllerTest < ActionController::TestCase context 'GET #index' do setup { get :index } should set_the_flash end context 'DELETE #destroy' do setup { delete :destroy } should_not set_the_flash end end
#### Qualifiers
##### []
Use `[]` to narrow the scope of the matcher to a particular key.
class PostsController < ApplicationController def index flash[:foo] = 'A candy bar' end end # RSpec describe PostsController do describe 'GET #index' do before { get :index } it { should set_the_flash[:foo] } it { should_not set_the_flash[:bar] } end end # Test::Unit class PostsControllerTest < ActionController::TestCase context 'GET #index' do setup { get :show } should set_the_flash[:foo] should_not set_the_flash[:bar] end end
##### to
Use `to` to assert that some key was set to a particular value, or that some key matches a particular regex.
class PostsController < ApplicationController def index flash[:foo] = 'A candy bar' end end # RSpec describe PostsController do describe 'GET #index' do before { get :index } it { should set_the_flash.to('A candy bar') } it { should set_the_flash.to(/bar/) } it { should set_the_flash[:foo].to('bar') } it { should_not set_the_flash[:foo].to('something else') } end end # Test::Unit class PostsControllerTest < ActionController::TestCase context 'GET #index' do setup { get :show } should set_the_flash.to('A candy bar') should set_the_flash.to(/bar/) should set_the_flash[:foo].to('bar') should_not set_the_flash[:foo].to('something else') end end
##### now
Use `now` to change the scope of the matcher to use the “now” hash instead of the usual “future” hash.
class PostsController < ApplicationController def show flash.now[:foo] = 'bar' end end # RSpec describe PostsController do describe 'GET #show' do before { get :show } it { should set_the_flash.now } it { should set_the_flash[:foo].now } it { should set_the_flash[:foo].to('bar').now } end end # Test::Unit class PostsControllerTest < ActionController::TestCase context 'GET #index' do setup { get :show } should set_the_flash.now should set_the_flash[:foo].now should set_the_flash[:foo].to('bar').now end end
@return [SetTheFlashMatcher]
# File lib/shoulda/matchers/action_controller/set_the_flash_matcher.rb, line 148 def set_the_flash SetTheFlashMatcher.new end
The `use_after_action` matcher is used to test that an after_action callback is defined within your controller.
class IssuesController < ApplicationController after_action :log_activity end # RSpec describe IssuesController do it { should use_after_action(:log_activity) } it { should_not use_after_action(:destroy_user) } end # Test::Unit class IssuesControllerTest < ActionController::TestCase should use_after_action(:log_activity) should_not use_after_action(:destroy_user) end
@return [CallbackMatcher]
# File lib/shoulda/matchers/action_controller/callback_matcher.rb, line 100 def use_after_action(callback) CallbackMatcher.new(callback, :after, :action) end
The `use_after_filter` matcher is used to test that an after_filter callback is defined within your controller.
class IssuesController < ApplicationController after_filter :log_activity end # RSpec describe IssuesController do it { should use_after_filter(:log_activity) } it { should_not use_after_filter(:destroy_user) } end # Test::Unit class IssuesControllerTest < ActionController::TestCase should use_after_filter(:log_activity) should_not use_after_filter(:destroy_user) end
@return [CallbackMatcher]
# File lib/shoulda/matchers/action_controller/callback_matcher.rb, line 50 def use_after_filter(callback) CallbackMatcher.new(callback, :after, :filter) end
The `use_around_action` matcher is used to test that an around_action callback is defined within your controller.
class ChangesController < ApplicationController around_action :wrap_in_transaction end # RSpec describe ChangesController do it { should use_around_action(:wrap_in_transaction) } it { should_not use_around_action(:save_view_context) } end # Test::Unit class ChangesControllerTest < ActionController::TestCase should use_around_action(:wrap_in_transaction) should_not use_around_action(:save_view_context) end
@return [CallbackMatcher]
# File lib/shoulda/matchers/action_controller/callback_matcher.rb, line 150 def use_around_action(callback) CallbackMatcher.new(callback, :around, :action) end
The `use_around_filter` matcher is used to test that an around_filter callback is defined within your controller.
class ChangesController < ApplicationController around_filter :wrap_in_transaction end # RSpec describe ChangesController do it { should use_around_filter(:wrap_in_transaction) } it { should_not use_around_filter(:save_view_context) } end # Test::Unit class ChangesControllerTest < ActionController::TestCase should use_around_filter(:wrap_in_transaction) should_not use_around_filter(:save_view_context) end
@return [CallbackMatcher]
# File lib/shoulda/matchers/action_controller/callback_matcher.rb, line 125 def use_around_filter(callback) CallbackMatcher.new(callback, :around, :filter) end
The `use_before_action` matcher is used to test that a before_action callback is defined within your controller.
class UsersController < ApplicationController before_action :authenticate_user! end # RSpec describe UsersController do it { should use_before_action(:authenticate_user!) } it { should_not use_before_action(:prevent_ssl) } end # Test::Unit class UsersControllerTest < ActionController::TestCase should use_before_action(:authenticate_user!) should_not use_before_action(:prevent_ssl) end
@return [CallbackMatcher]
# File lib/shoulda/matchers/action_controller/callback_matcher.rb, line 75 def use_before_action(callback) CallbackMatcher.new(callback, :before, :action) end
The `use_before_filter` matcher is used to test that a before_filter callback is defined within your controller.
class UsersController < ApplicationController before_filter :authenticate_user! end # RSpec describe UsersController do it { should use_before_filter(:authenticate_user!) } it { should_not use_before_filter(:prevent_ssl) } end # Test::Unit class UsersControllerTest < ActionController::TestCase should use_before_filter(:authenticate_user!) should_not use_before_filter(:prevent_ssl) end
@return [CallbackMatcher]
# File lib/shoulda/matchers/action_controller/callback_matcher.rb, line 25 def use_before_filter(callback) CallbackMatcher.new(callback, :before, :filter) end
Generated with the Darkfish Rdoc Generator 2.