Rails: multiple get requests in a single functional test

functional-testing, ruby-on-rails

Solution

One important distinction I've noticed in functional tests (as opposed to integration) is that the state of a controller does not seem to be reset between requests, which can lead to unexpected results. For example, consider this (contrived) controller:

class ThingyController < ApplicationController
  def one 
    @thingy = Thingy.first
    render :nothing => true
  end 

  def two 
    render :nothing => true
  end 
end

Action 'one' sets @thingy, while action 'two' doesn't. However, this functional test fails:

test "thingy should not exist in second request" do
  get :one
  assert_not_nil assigns(:thingy), "thingy should exist in get_one"
  get :two
  assert_nil assigns(:thingy), "thingy should be absent in get_two"
end

Presumably, it is because the @thingy from the first request remains as an instance variable in the controller for the duration of the test method.

While you can certainly make multiple get/put/etc calls within one test, I think they are not designed to test more than one action per test method. Per the Rails API TestCase docs:

Functional tests allow you to test a single controller action per test method. This should not be confused with integration tests (see ActionDispatch::IntegrationTest), which are more like “stories” that can involve multiple controllers and multiple actions (i.e. multiple different HTTP requests).

If you really wish to combine the two actions, perhaps an integration test would be a better approach.

Problem

I would like to group some get requests in the same tests but I get erratic behavior. I have the following two tests: ``` test 'index for local seller (same site)' do seller = FactoryGirl.create :seller, business_site: @open_or.business_site get :index, nil, {user_id: seller.to_param } assert_select "table#order_requests tr##{@controller.view_context.dom_id @open_or}" end test 'index for local seller (different site)' do seller = FactoryGirl.create :seller_local get :index, nil, {user_id: seller.to_param } assert_select "table#order_requests tr##{@controller.view_context.dom_id @open_or}", false end ``` which I would like to combine under one test but if I do so, the second assert will wrongly fail (Expected exactly 0 elements matching "table#order_requests tr#order_request_1000244799", found 1.). I don't really understand why? Something might not be reset properly for the second 'get' call. I looked for ways to 'reset' the request without success. Related: making two requests to the same controller in rails integrations specs

Original source

Related problems