1 require 'active_support/test_case'
3 module ActionController
4 class NonInferrableControllerError
< ActionControllerError
7 super "Unable to determine the controller to test from #{name}. " +
8 "You'll need to specify it using 'tests YourController' in your " +
9 "test case definition. This could mean that #{inferred_controller_name} does not exist " +
10 "or it contains syntax errors"
13 def inferred_controller_name
14 @name.sub(/Test$/, '')
18 # Superclass for ActionController functional tests. Functional tests allow you to
19 # test a single controller action per test method. This should not be confused with
20 # integration tests (see ActionController::IntegrationTest), which are more like
21 # "stories" that can involve multiple controllers and mutliple actions (i.e. multiple
22 # different HTTP requests).
26 # Functional tests are written as follows:
27 # 1. First, one uses the +get+, +post+, +put+, +delete+ or +head+ method to simulate
29 # 2. Then, one asserts whether the current state is as expected. "State" can be anything:
30 # the controller's HTTP response, the database contents, etc.
34 # class BooksControllerTest < ActionController::TestCase
36 # # Simulate a POST response with the given HTTP parameters.
37 # post(:create, :book => { :title => "Love Hina" })
39 # # Assert that the controller tried to redirect us to
40 # # the created book's URI.
41 # assert_response :found
43 # # Assert that the controller really put the book in the database.
44 # assert_not_nil Book.find_by_title("Love Hina")
48 # == Special instance variables
50 # ActionController::TestCase will also automatically provide the following instance
51 # variables for use in the tests:
53 # <b>@controller</b>::
54 # The controller instance that will be tested.
56 # An ActionController::TestRequest, representing the current HTTP
57 # request. You can modify this object before sending the HTTP request. For example,
58 # you might want to set some session properties before sending a GET request.
60 # An ActionController::TestResponse object, representing the response
61 # of the last HTTP response. In the above example, <tt>@response</tt> becomes valid
62 # after calling +post+. If the various assert methods are not sufficient, then you
63 # may use this object to inspect the HTTP response in detail.
65 # (Earlier versions of Rails required each functional test to subclass
66 # Test::Unit::TestCase and define @controller, @request, @response in +setup+.)
68 # == Controller is automatically inferred
70 # ActionController::TestCase will automatically infer the controller under test
71 # from the test class name. If the controller cannot be inferred from the test
72 # class name, you can explicity set it with +tests+.
74 # class SpecialEdgeCaseWidgetsControllerTest < ActionController::TestCase
75 # tests WidgetController
77 class TestCase
< ActiveSupport
::TestCase
78 # When the request.remote_addr remains the default for testing, which is 0.0.0.0, the exception is simply raised inline
79 # (bystepping the regular exception handling from rescue_action). If the request.remote_addr is anything else, the regular
80 # rescue_action process takes place. This means you can test your rescue_action code by setting remote_addr to something else
83 # The exception is stored in the exception accessor for further inspection.
84 module RaiseActionExceptions
85 attr_accessor
:exception
87 def rescue_action_without_handler(e
)
90 if request
.remote_addr
== "0.0.0.0"
98 setup
:setup_controller_request_and_response
100 @
@controller_class = nil
103 # Sets the controller class name. Useful if the name can't be inferred from test class.
104 # Expects +controller_class+ as a constant. Example: <tt>tests WidgetController</tt>.
105 def tests(controller_class
)
106 self.controller_class
= controller_class
109 def controller_class
=(new_class
)
110 prepare_controller_class(new_class
)
111 write_inheritable_attribute(:controller_class, new_class
)
115 if current_controller_class
= read_inheritable_attribute(:controller_class)
116 current_controller_class
118 self.controller_class
= determine_default_controller_class(name
)
122 def determine_default_controller_class(name
)
123 name
.sub(/Test$/, '').constantize
125 raise NonInferrableControllerError
.new(name
)
128 def prepare_controller_class(new_class
)
129 new_class
.send
:include, RaiseActionExceptions
133 def setup_controller_request_and_response
134 @controller = self.class.controller_class
.new
135 @controller.request
= @request = TestRequest
.new
136 @response = TestResponse
.new
138 @controller.params
= {}
139 @controller.send(:initialize_current_url)
142 # Cause the action to be rescued according to the regular rules for rescue_action when the visitor is not local
143 def rescue_action_in_public
!
144 @request.remote_addr
= '208.77.188.166' # example.com