如何为使用Session的Rails 5控制器编写测试?实战场景求解
Hey there! Let's tackle this test case together since you're working through the Agile Web Development with Rails 5.1 book—great choice by the way!
First, we need to cover two key scenarios for your cart ownership validation: accessing a cart that belongs to the user's session (should work) and accessing a cart tied to someone else's session (should be blocked). We'll use Rails' built-in Minitest framework (which the book uses) for these tests.
These tests will live in test/controllers/carts_controller_test.rb.
Step 1: Setup Test Data
First, add a setup method to create test carts and set up a valid session:
class CartsControllerTest < ActionDispatch::IntegrationTest setup do # Create two distinct carts @user_cart = Cart.create @foreign_cart = Cart.create # Link one cart to the test session session[:cart_id] = @user_cart.id end
Step 2: Test Accessing the User's Own Cart
This test verifies that the user can successfully view their assigned cart:
test "should allow access to user's own cart" do get cart_url(@user_cart) # Check that the request succeeds assert_response :success # Optional: Confirm the correct cart is passed to the view assert_equal @user_cart, assigns(:cart) end
Step 3: Test Blocking Access to Foreign Carts
This test ensures the user can't access a cart that doesn't match their session. Adjust the assertions based on what your invalid_cart method does (e.g., redirect, flash message, or 403 error):
test "should block access to foreign cart" do get cart_url(@foreign_cart) # If your invalid_cart redirects to the store with a flash message assert_redirected_to store_index_path assert_not_nil flash[:error] # Match the flash key you use in your controller # If you return a 403 Forbidden instead, use this line instead: # assert_response :forbidden end
Step 4: Wrap Up the Test Class
Don't forget to close the class definition:
end
Quick Check for Your Controller Logic
Since your original code was cut off, here's a polished version of the controller code to align with the tests:
class CartsController < ApplicationController def show @cart = Cart.find(params[:id]) invalid_cart if @cart.id != session[:cart_id] end private def invalid_cart logger.error "Attempted access to invalid cart ##{params[:id]}" flash[:error] = "You don't have permission to access that cart!" redirect_to store_index_path end end
Run your tests with rails test—they should pass if your controller logic is working as intended!
内容的提问来源于stack exchange,提问作者rderik

