Bird
Raised Fist0
Ruby on Railsframework~10 mins

Controller tests in Ruby on Rails - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Controller tests
Write test for controller action
↓
Run test suite
↓
Rails runs controller action
↓
Controller processes request
↓
Controller returns response
↓
Test checks response and side effects
↓
Test passes or fails
↓
Fix code or test if needed
↓
Repeat
Controller tests run your Rails controller actions and check their responses and effects step-by-step.
Execution Sample
Ruby on Rails
test "should get index" do
  get :index
  assert_response :success
  assert_not_nil assigns(:items)
end
This test calls the index action, checks for success response, and verifies assigned variables.
Execution Table
StepActionController StateResponseTest AssertionResult
1Call get :indexProcessing index actionPendingNone yetContinue
2Controller fetches itemsItems loaded into @itemsPendingNone yetContinue
3Controller renders index viewReady to respond200 OKassert_response :successPass
4Test checks assigns(:items)@items present200 OKassert_not_nil assigns(:items)Pass
5Test endsCompleted200 OKAll assertions passedTest Passed
💡 Test ends after all assertions pass or fail
Variable Tracker
VariableStartAfter Step 2After Step 3Final
@itemsnilArray of items loadedArray of items loadedArray of items loaded
Key Moments - 3 Insights
Why does the test check 'assigns(:items)' after calling get :index?
Because the controller sets @items in the index action, the test verifies it to ensure the controller prepared data for the view (see execution_table step 4).
What does 'assert_response :success' check in the test?
It checks that the controller responded with HTTP status 200 OK, meaning the request was handled successfully (see execution_table step 3).
Why do we call 'get :index' in the test?
Calling 'get :index' simulates a browser requesting the index page, triggering the controller action to run (see execution_table step 1).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what is the response status after the controller renders the index view?
A200 OK
B404 Not Found
C500 Internal Server Error
D302 Redirect
💡 Hint
Check the Response column at Step 3 in the execution_table
At which step does the test verify that @items is not nil?
AStep 2
BStep 4
CStep 3
DStep 5
💡 Hint
Look at the Test Assertion column in the execution_table
If the controller did not assign @items, which test assertion would fail?
Aassert_response :success
Bget :index
Cassert_not_nil assigns(:items)
DTest ends
💡 Hint
Refer to the assertion checking assigns(:items) in execution_table step 4
Concept Snapshot
Controller tests in Rails:
- Use HTTP verbs like get, post to call actions
- Check response status with assert_response
- Verify instance variables with assigns(:var)
- Ensure controller processes requests and renders views correctly
- Run tests to catch errors early
Full Transcript
Controller tests in Rails simulate browser requests to controller actions. The test calls an action like index using get :index. The controller runs the action, loads data into instance variables like @items, and renders a view. The test then checks the HTTP response status to confirm success and verifies that expected variables are assigned. If all assertions pass, the test passes. This process helps ensure your controller behaves as expected before deploying your app.

Practice

(1/5)
1. What is the main purpose of a controller test in Rails?
easy
A. To check if web requests respond correctly and perform expected actions
B. To test database schema changes
C. To verify CSS styles are applied properly
D. To check JavaScript functions run without errors

Solution

  1. Step 1: Understand controller test role

    Controller tests simulate web requests to check if the controller responds correctly.
  2. Step 2: Compare options

    Only To check if web requests respond correctly and perform expected actions describes checking web requests and expected actions, which is the controller test's purpose.
  3. Final Answer:

    To check if web requests respond correctly and perform expected actions -> Option A
  4. Quick Check:

    Controller tests check web requests = A [OK]
Hint: Controller tests simulate web requests to check responses [OK]
Common Mistakes:
  • Confusing controller tests with database or view tests
  • Thinking controller tests check CSS or JavaScript
  • Assuming controller tests modify database schema
2. Which of the following is the correct syntax to simulate a GET request to the index action in a Rails controller test?
easy
A. get('/index')
B. get index
C. get index()
D. get :index

Solution

  1. Step 1: Recall Rails controller test syntax

    In Rails controller tests, the correct way to simulate a GET request is using get :action_name.
  2. Step 2: Analyze options

    get :index uses get :index, which is correct syntax. Others are invalid or incorrect Ruby syntax.
  3. Final Answer:

    get :index -> Option D
  4. Quick Check:

    Use symbol with get method = C [OK]
Hint: Use get :action_name with a symbol for controller tests [OK]
Common Mistakes:
  • Using string or method call syntax instead of symbol
  • Omitting colon before action name
  • Using parentheses incorrectly
3. Given this controller test snippet:
get :show, params: { id: 1 }
assert_response :success
assert_not_nil assigns(:user)

What does assert_not_nil assigns(:user) check?
medium
A. That the @user variable was assigned in the controller
B. That the user with id 1 exists in the database
C. That the response body contains the word 'user'
D. That the controller redirected to the user page

Solution

  1. Step 1: Understand assigns method in controller tests

    The assigns(:user) method accesses the instance variable @user set by the controller.
  2. Step 2: Interpret assert_not_nil usage

    assert_not_nil assigns(:user) checks that @user is not nil, meaning it was assigned.
  3. Final Answer:

    That the @user variable was assigned in the controller -> Option A
  4. Quick Check:

    assigns(:user) checks @user variable = B [OK]
Hint: assigns(:var) checks controller instance variable @var [OK]
Common Mistakes:
  • Thinking assigns checks database existence
  • Confusing assigns with response content
  • Assuming assigns checks redirects
4. Identify the error in this Rails controller test code:
post :create, user: { name: 'Alice' }
assert_redirected_to user_path(assigns(:user))
medium
A. assert_redirected_to should be assert_response
B. Using post instead of get for create action
C. Missing params: keyword before user hash in post request
D. assigns(:user) cannot be used in controller tests

Solution

  1. Step 1: Check syntax for post request with parameters

    In Rails 5+, parameters must be wrapped inside params: keyword.
  2. Step 2: Analyze given code

    The code uses post :create, user: { name: 'Alice' } missing params:, causing syntax error.
  3. Final Answer:

    Missing params: keyword before user hash in post request -> Option C
  4. Quick Check:

    Use params: for parameters in post requests = A [OK]
Hint: Always use params: keyword for request parameters [OK]
Common Mistakes:
  • Omitting params: keyword in request methods
  • Confusing HTTP verbs for actions
  • Misusing assertion methods
5. You want to test that after creating a new user, the controller redirects to the user's show page and sets a flash notice. Which test code correctly checks both behaviors?
hard
A. post :create, params: { user: { name: 'Bob' } } assert_response :redirect assert_nil flash[:notice]
B. post :create, params: { user: { name: 'Bob' } } assert_redirected_to user_path(assigns(:user)) assert_equal 'User created!', flash[:notice]
C. get :create, params: { user: { name: 'Bob' } } assert_redirected_to user_path(assigns(:user)) assert flash[:alert] == 'User created!'
D. post :create, user: { name: 'Bob' } assert_response :success assert flash[:notice] == 'User created!'

Solution

  1. Step 1: Check HTTP verb and parameters

    Creating a user uses POST with params: keyword, so post :create, params: { user: { name: 'Bob' } } assert_redirected_to user_path(assigns(:user)) assert_equal 'User created!', flash[:notice] is correct here.
  2. Step 2: Verify assertions for redirect and flash

    post :create, params: { user: { name: 'Bob' } } assert_redirected_to user_path(assigns(:user)) assert_equal 'User created!', flash[:notice] asserts redirect to user's show page and flash notice equals 'User created!'. This matches the requirement.
  3. Step 3: Eliminate incorrect options

    post :create, user: { name: 'Bob' } assert_response :success assert flash[:notice] == 'User created!' misses params: keyword and uses assert_response :success instead of redirect. get :create, params: { user: { name: 'Bob' } } assert_redirected_to user_path(assigns(:user)) assert flash[:alert] == 'User created!' uses GET instead of POST and wrong flash key. post :create, params: { user: { name: 'Bob' } } assert_response :redirect assert_nil flash[:notice] asserts flash[:notice] is nil, which is wrong.
  4. Final Answer:

    post :create, params: { user: { name: 'Bob' } } assert_redirected_to user_path(assigns(:user)) assert_equal 'User created!', flash[:notice] -> Option B
  5. Quick Check:

    POST with params, redirect, and flash notice = D [OK]
Hint: Use post with params:, assert_redirected_to, and assert_equal flash [OK]
Common Mistakes:
  • Using get instead of post for create action
  • Forgetting params: keyword
  • Checking wrong flash key or missing redirect assertion
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard