module Shoulda::Matchers::ActionController
Public Instance Methods
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 `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 #list' do before { get :list } it { should redirect_to(posts_path) } it { should redirect_to(action: :index) } end end # Test::Unit class PostsControllerTest < ActionController::TestCase context 'GET #list' do setup { get :list } 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. 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 # RSpec describe PostsController do describe 'GET #show' do before { get :show } it { should render_template('show') } end end # Test::Unit class PostsControllerTest < ActionController::TestCase context 'GET #show' do setup { get :show } should render_template('show') end end
@return [RenderTemplateMatcher]
# File lib/shoulda/matchers/action_controller/render_template_matcher.rb, line 34 def render_template(options = {}, message = nil) RenderTemplateMatcher.new(options, message, self) end
The `render_with_layout` matcher tests that an action is rendered with a certain 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
@return [RenderWithLayoutMatcher]
# File lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb, line 33 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`.
Given these routes:
My::Application.routes.draw do get '/posts', controller: 'posts', action: 'index' get '/posts/:id' => 'posts#show' end
You can choose to keep your routing tests under the test file for one controller:
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 if you like, you can keep all of your routing tests in one file. Just be sure to always specify a controller as `route` won't be able to figure it out otherwise:
# RSpec describe 'Routing' do it { should route(:get, '/posts').to(controller: :posts, action: :index) } it { should route(:get, '/posts/1').to('posts#show', id: 1) } 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
@return [RouteMatcher]
# File lib/shoulda/matchers/action_controller/route_matcher.rb, line 54 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