Module: Shoulda::ActionController::Macros

Includes:
Matchers
Included in:
Test::Unit::TestCase
Defined in:
lib/shoulda/action_controller/macros.rb

Overview

Macro test helpers for your controllers

By using the macro helpers you can quickly and easily create concise and easy to read test suites.

This code segment:

context "on GET to :show for first record" do
  setup do
    get :show, :id => 1
  end

  should_assign_to :user
  should_respond_with :success
  should_render_template :show
  should_not_set_the_flash

  should "do something else really cool" do
    assert_equal 1, assigns(:user).id
  end
end

Would produce 5 tests for the show action

Instance Method Summary collapse

Methods included from Matchers

#assign_to, #filter_param, #render_with_layout, #respond_with, #respond_with_content_type, #route, #set_session, #set_the_flash

Instance Method Details

#should_assign_to(*names, &block) ⇒ Object

Macro that creates a test asserting that the controller assigned to each of the named instance variable(s).

Options:

  • :class - The expected class of the instance variable being checked.

  • :equals - A string which is evaluated and compared for equality with

the instance variable being checked.

Example:

should_assign_to :user, :posts
should_assign_to :user, :class => User
should_assign_to(:user) { @user }


82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/shoulda/action_controller/macros.rb', line 82

def should_assign_to(*names, &block)
  opts = names.extract_options!
  if opts[:equals]
    warn "[DEPRECATION] should_assign_to :var, :equals => 'val' " <<
         "is deprecated. Use should_assign_to(:var) { 'val' } instead."
  end
  names.each do |name|
    matcher = assign_to(name).with_kind_of(opts[:class])
    test_name = matcher.description
    test_name << " which is equal to #{opts[:equals]}" if opts[:equals]
    should test_name do
      if opts[:equals]
        instantiate_variables_from_assigns do
          expected_value = eval(opts[:equals],
                                self.send(:binding),
                                __FILE__,
                                __LINE__)
          matcher = matcher.with(expected_value)
        end
      elsif block
        expected_value = instance_eval(&block)
        matcher = matcher.with(expected_value)
      end

      assert_accepts matcher, @controller
    end
  end
end

#should_filter_params(*keys) ⇒ Object

Macro that creates a test asserting that filter_parameter_logging is set for the specified keys

Example:

should_filter_params :password, :ssn


60
61
62
63
64
65
66
67
# File 'lib/shoulda/action_controller/macros.rb', line 60

def should_filter_params(*keys)
  keys.each do |key|
    matcher = filter_param(key)
    should matcher.description do
      assert_accepts matcher, @controller
    end
  end
end

#should_not_assign_to(*names) ⇒ Object

Macro that creates a test asserting that the controller did not assign to any of the named instance variable(s).

Example:

should_not_assign_to :user, :posts


117
118
119
120
121
122
123
124
# File 'lib/shoulda/action_controller/macros.rb', line 117

def should_not_assign_to(*names)
  names.each do |name|
    matcher = assign_to(name)
    should "not #{matcher.description}" do
      assert_rejects matcher, @controller
    end
  end
end

#should_not_set_the_flashObject

Macro that creates a test asserting that the flash is empty. Same as



50
51
52
# File 'lib/shoulda/action_controller/macros.rb', line 50

def should_not_set_the_flash
  should_set_the_flash_to nil
end

#should_redirect_to(description, &block) ⇒ Object

Macro that creates a test asserting that the controller returned a redirect to the given path. The given string is evaled to produce the resulting redirect path. All of the instance variables set by the controller are available to the evaled string. Example:

should_redirect_to("the user's profile") { user_url(@user) }


226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
# File 'lib/shoulda/action_controller/macros.rb', line 226

def should_redirect_to(description, &block)
  unless block
    warn "[DEPRECATION] should_redirect_to without a block is " <<
         "deprecated. Use should_redirect_to('somewhere') { } instead."
  end
  should "redirect to #{description}" do
    if block
      url = instance_eval(&block)
    else
      instantiate_variables_from_assigns do
        url = eval(description, self.send(:binding), __FILE__, __LINE__)
      end
    end
    assert_redirected_to url
  end
end

#should_render_template(template) ⇒ Object

Macro that creates a test asserting that the controller rendered the given template. Example:

should_render_template :new


191
192
193
194
195
# File 'lib/shoulda/action_controller/macros.rb', line 191

def should_render_template(template)
  should "render template #{template.inspect}" do
    assert_template template.to_s
  end
end

#should_render_with_layout(expected_layout = 'application') ⇒ Object

Macro that creates a test asserting that the controller rendered with the given layout. Example:

should_render_with_layout 'special'


201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/shoulda/action_controller/macros.rb', line 201

def should_render_with_layout(expected_layout = 'application')
  matcher = render_with_layout(expected_layout)
  if expected_layout
    should matcher.description do
      assert_accepts matcher, @controller
    end
  else
    should "render without layout" do
      assert_rejects matcher, @controller
    end
  end
end

#should_render_without_layoutObject

Macro that creates a test asserting that the controller rendered without a layout. Same as @should_render_with_layout false@



216
217
218
# File 'lib/shoulda/action_controller/macros.rb', line 216

def should_render_without_layout
  should_render_with_layout nil
end

#should_respond_with(response) ⇒ Object

Macro that creates a test asserting that the controller responded with a ‘response’ status code. Example:

should_respond_with :success


130
131
132
133
134
135
# File 'lib/shoulda/action_controller/macros.rb', line 130

def should_respond_with(response)
  should "respond with #{response}" do
    matcher = respond_with(response)
    assert_accepts matcher, @controller
  end
end

#should_respond_with_content_type(content_type) ⇒ Object

Macro that creates a test asserting that the response content type was ‘content_type’. Example:

should_respond_with_content_type 'application/rss+xml'
should_respond_with_content_type :rss
should_respond_with_content_type /rss/


143
144
145
146
147
148
# File 'lib/shoulda/action_controller/macros.rb', line 143

def should_respond_with_content_type(content_type)
  should "respond with content type of #{content_type}" do
    matcher = respond_with_content_type(content_type)
    assert_accepts matcher, @controller
  end
end

#should_return_from_session(key, expected) ⇒ Object

Deprecated. See should_set_session



181
182
183
184
185
# File 'lib/shoulda/action_controller/macros.rb', line 181

def should_return_from_session(key, expected)
  warn "[DEPRECATION] should_require_attributes is deprecated. " <<
       "Use should_set_session instead."
  should_set_session(key, expected)
end

#should_route(method, path, options) ⇒ Object

Macro that creates a routing test. It tries to use the given HTTP method on the given path, and asserts that it routes to the given options.

If you don’t specify a :controller, it will try to guess the controller based on the current test.

to_param is called on the options given.

Examples:

should_route :get, "/posts", :controller => :posts, :action => :index
should_route :get, "/posts/new", :action => :new
should_route :post, "/posts", :action => :create
should_route :get, "/posts/1", :action => :show, :id => 1
should_route :edit, "/posts/1", :action => :show, :id => 1
should_route :put, "/posts/1", :action => :update, :id => 1
should_route :delete, "/posts/1", :action => :destroy, :id => 1
should_route :get, "/users/1/posts/1",
  :action => :show, :id => 1, :user_id => 1


264
265
266
267
268
269
270
271
272
273
274
# File 'lib/shoulda/action_controller/macros.rb', line 264

def should_route(method, path, options)
  unless options[:controller]
    options[:controller] = self.name.gsub(/ControllerTest$/, '').tableize
  end

  matcher = route(method, path).to(options)

  should matcher.description do
    assert_accepts matcher.in_context(self), self
  end
end

#should_set_session(key, expected = nil, &block) ⇒ Object

Macro that creates a test asserting that a value returned from the session is correct. The given string is evaled to produce the resulting redirect path. All of the instance variables set by the controller are available to the evaled string. Example:

should_set_session(:user_id) { '@user.id' }
should_set_session(:message) { "Free stuff" }


157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/shoulda/action_controller/macros.rb', line 157

def should_set_session(key, expected = nil, &block)
  matcher = set_session(key)
  if expected
    warn "[DEPRECATION] should_set_session :key, 'val' is deprecated. " <<
         "Use should_set_session(:key) { 'val' } instead."
  end
  should matcher.description do
    if expected
      instantiate_variables_from_assigns do
        expected_value = eval(expected, 
                              self.send(:binding),
                              __FILE__,
                              __LINE__)
        matcher = matcher.to(expected_value)
      end
    else
      expected_value = instance_eval(&block)
      matcher = matcher.to(expected_value)
    end
    assert_accepts matcher, @controller
  end
end

#should_set_the_flash_to(val) ⇒ Object

Macro that creates a test asserting that the flash contains the given value. val can be a String, a Regex, or nil (indicating that the flash should not be set)

Example:

should_set_the_flash_to "Thank you for placing this order."
should_set_the_flash_to /created/i
should_set_the_flash_to nil


35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/shoulda/action_controller/macros.rb', line 35

def should_set_the_flash_to(val)
  matcher = set_the_flash.to(val)
  if val
    should matcher.description do
      assert_accepts matcher, @controller
    end
  else
    should "not #{matcher.description}" do
      assert_rejects matcher, @controller
    end
  end
end