Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: multiple get requests in a single functional test

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

like image 536
gamov Avatar asked Dec 12 '12 04:12

gamov


People also ask

How does Ruby on rails handle multiple requests?

Rails automatically allows various operations to be performed at the same time. When using a threaded web server, such as the default Puma, multiple HTTP requests will be served simultaneously, with each request provided its own controller instance.

How many requests can Ruby on rails handle?

600 requests/second. 180 application instances (mongrel) About 300ms average server response time.

What is Minitest?

What is Minitest? Minitest is a testing tool for Ruby that provides a complete suite of testing facilities. It also supports behaviour-driven development, mocking and benchmarking.

How do you run a Minitest in rails?

To run a Minitest test, the only setup you really need is to require the autorun file at the beginning of a test file: require 'minitest/autorun' . This is good if you'd like to keep the code small. A better way to get started with Minitest is to have Bundler create a template project for you.


1 Answers

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.

like image 140
twelve17 Avatar answered Oct 10 '22 20:10

twelve17