module ActionController::TestCase::Behavior
def build_response(klass)
def build_response(klass) klass.create end
def check_required_ivars
def check_required_ivars # Check for required instance variables so we can give an # understandable error message. [:@routes, :@controller, :@request, :@response].each do |iv_name| if !instance_variable_defined?(iv_name) || instance_variable_get(iv_name).nil? raise "#{iv_name} is nil: make sure you set it in your test's setup method." end end end
def controller_class_name
def controller_class_name @controller.class.anonymous? ? "anonymous" : @controller.class.controller_path end
def delete(action, **args)
Simulate a DELETE request with the given parameters and set/volley the response.
def delete(action, **args) process(action, method: "DELETE", **args) end
def document_root_element
def document_root_element html_document.root end
def generated_path(generated_extras)
def generated_path(generated_extras) generated_extras[0] end
def get(action, **args)
Note that the request method is not verified. The different methods are
flash: { notice: 'This is flash message' }
session: { user_id: 1 },
params: { id: 7 },
get :show,
Example sending parameters, session, and setting a flash message:
+post+, +patch+, +put+, +delete+, and +head+.
You can also simulate POST, PATCH, PUT, DELETE, and HEAD requests with
- +flash+: A hash of parameters to store in the flash. This may be +nil+.
- +session+: A hash of parameters to store in the session. This may be +nil+.
(application/x-www-form-urlencoded or multipart/form-data).
- +body+: The request body with a string that is appropriately encoded
- +params+: The hash with HTTP parameters that you want to pass. This may be +nil+.
- +action+: The controller action to call.
Simulate a GET request with the given parameters.
def get(action, **args) res = process(action, method: "GET", **args) cookies.update res.cookies res end
def head(action, **args)
Simulate a HEAD request with the given parameters and set/volley the response.
def head(action, **args) process(action, method: "HEAD", **args) end
def patch(action, **args)
Simulate a PATCH request with the given parameters and set/volley the response.
def patch(action, **args) process(action, method: "PATCH", **args) end
def post(action, **args)
Simulate a POST request with the given parameters and set/volley the response.
def post(action, **args) process(action, method: "POST", **args) end
def process(action, method: "GET", params: nil, session: nil, body: nil, flash: {}, format: nil, xhr: false, as: nil)
ActionDispatch::IntegrationTest for making multiple requests in the same test.
but it's not guaranteed that all Rails internal state will be reset. Prefer
variables that are set in one request will not persist to the next request,
It's not recommended to make more than one request in the same test. Instance
respectively which will make tests more expressive.
prefer using #get, #post, #patch, #put, #delete and #head methods
To simulate +GET+, +POST+, +PATCH+, +PUT+, +DELETE+, and +HEAD+ requests
flash: { notice: 'This is flash message' }
session: { user_id: 1 },
},
user: { name: 'Gaurish Sharma', email: 'user@example.com' }
params: {
method: 'POST',
process :create,
Example calling +create+ action and sending two params:
to a mime type.
- +as+: Content type. Defaults to +nil+. Must be a symbol that corresponds
- +format+: Request format. Defaults to +nil+. Can be string or symbol.
- +flash+: A hash of parameters to store in the flash. This may be +nil+.
- +session+: A hash of parameters to store in the session. This may be +nil+.
(application/x-www-form-urlencoded or multipart/form-data).
- +body+: The request body with a string that is appropriately encoded
- +params+: The hash with HTTP parameters that you want to pass. This may be +nil+.
are +GET+, +POST+, +PATCH+, +PUT+, +DELETE+, +HEAD+. Defaults to +GET+. Can be a symbol.
- +method+: Request method used to send the HTTP request. Possible values
- +action+: The controller action to call.
parameters and set/volley the response.
Simulate an HTTP request to +action+ by specifying request method,
def process(action, method: "GET", params: nil, session: nil, body: nil, flash: {}, format: nil, xhr: false, as: nil) check_required_ivars @controller.clear_instance_variables_between_requests action = +action.to_s http_method = method.to_s.upcase @html_document = nil cookies.update(@request.cookies) cookies.update_cookies_from_jar @request.set_header "HTTP_COOKIE", cookies.to_header @request.delete_header "action_dispatch.cookies" @request = TestRequest.new scrub_env!(@request.env), @request.session, @controller.class @response = build_response @response_klass @response.request = @request @controller.recycle! if body @request.set_header "RAW_POST_DATA", body end @request.set_header "REQUEST_METHOD", http_method if as @request.content_type = Mime[as].to_s format ||= as end parameters = (params || {}).symbolize_keys if format parameters[:format] = format end setup_request(controller_class_name, action, parameters, session, flash, xhr) process_controller_response(action, cookies, xhr) end
def process_controller_response(action, cookies, xhr)
def process_controller_response(action, cookies, xhr) begin @controller.recycle! wrap_execution { @controller.dispatch(action, @request, @response) } ensure @request = @controller.request @response = @controller.response if @request.have_cookie_jar? unless @request.cookie_jar.committed? @request.cookie_jar.write(@response) cookies.update(@request.cookie_jar.instance_variable_get(:@cookies)) end end @response.prepare! if flash_value = @request.flash.to_session_value @request.session["flash"] = flash_value else @request.session.delete("flash") end if xhr @request.delete_header "HTTP_X_REQUESTED_WITH" @request.delete_header "HTTP_ACCEPT" end @request.query_string = "" @response.sent! end @response end
def put(action, **args)
Simulate a PUT request with the given parameters and set/volley the response.
def put(action, **args) process(action, method: "PUT", **args) end
def query_parameter_names(generated_extras)
def query_parameter_names(generated_extras) generated_extras[1] + [:controller, :action] end
def scrub_env!(env)
def scrub_env!(env) env.delete_if do |k, _| k.start_with?("rack.request", "action_dispatch.request", "action_dispatch.rescue") end env["rack.input"] = StringIO.new env.delete "CONTENT_LENGTH" env.delete "RAW_POST_DATA" env end
def setup_controller_request_and_response
def setup_controller_request_and_response @controller = nil unless defined? @controller @response_klass = ActionDispatch::TestResponse if klass = self.class.controller_class if klass < ActionController::Live @response_klass = LiveTestResponse end unless @controller begin @controller = klass.new rescue warn "could not construct controller #{klass}" if $VERBOSE end end end @request = TestRequest.create(@controller.class) @response = build_response @response_klass @response.request = @request if @controller @controller.request = @request @controller.params = {} end end
def setup_request(controller_class_name, action, parameters, session, flash, xhr)
def setup_request(controller_class_name, action, parameters, session, flash, xhr) generated_extras = @routes.generate_extras(parameters.merge(controller: controller_class_name, action: action)) generated_path = generated_path(generated_extras) query_string_keys = query_parameter_names(generated_extras) @request.assign_parameters(@routes, controller_class_name, action, parameters, generated_path, query_string_keys) @request.session.update(session) if session @request.flash.update(flash || {}) if xhr @request.set_header "HTTP_X_REQUESTED_WITH", "XMLHttpRequest" @request.fetch_header("HTTP_ACCEPT") do |k| @request.set_header k, [Mime[:js], Mime[:html], Mime[:xml], "text/xml", "*/*"].join(", ") end end @request.fetch_header("SCRIPT_NAME") do |k| @request.set_header k, @controller.config.relative_url_root end end
def wrap_execution(&block)
def wrap_execution(&block) if ActionController::TestCase.executor_around_each_request && defined?(Rails.application) && Rails.application Rails.application.executor.wrap(&block) else yield end end