Minitest测试助手模拟会话时遇路由错误求助
管理员权限控制测试中的路由错误解决方法
问题描述
实现仅管理员可创建文章的权限控制时,使用Minitest编写CategoriesController测试,调用自定义sign_in_as方法模拟管理员登录时,出现如下路由错误:
ActionController::UrlGenerationError: No route matches {:action=>"/login_categories", :controller=>"categories", :params=>{:email=>"fardeenmhs@hotmail.com", :password=>"fardeen"}} test/test_helper.rb:16:in `sign_in_as'
相关代码
CategoriesController测试代码
require 'test_helper' class CategoriesControllerTest < ActionController::TestCase setup do @category = Category.create(name: "Sports") @admin_user = User.create(username: "fardeen", email: "fardeenmhs@hotmail.com",password: "fardeen", admin: true) end test "should get index" do get :index assert_response :success # assert_not_nil assigns(:categories) end test "should get new" do sign_in_as(@admin_user) get :new assert_response :success end test "should create category" do sign_in_as(@admin_user) assert_difference('Category.count',1) do post :create, category: { name:"Travel" } end assert_redirected_to category_path(Category.last) end test "should not create category if not admin" do assert_no_difference('Category.count') do post :create, category: { name:"Travel" } end assert_redirected_to categories_path end test "should show category" do get :show, id: @category assert_response :success end test "should get edit" do sign_in_as(@admin_user) get :edit, id: @category assert_response :success end end
sign_in_as助手方法代码
ENV["RAILS_ENV"] ||= "test" require File.expand_path('../../config/environment', __FILE__) require 'rails/test_help' class ActiveSupport::TestCase ActiveRecord::Migration.check_pending! # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. # # Note: You'll currently still have to declare fixtures explicitly in integration tests # -- they do not yet inherit this setting fixtures :all # Add more helper methods to be used by all tests here... def sign_in_as(user) post login_path, params: {email: user.email, password: "fardeen"} end end
路由信息
Prefix Verb URI Pattern Controller#Action root GET / pages#Welcome about GET /about(.:format) pages#about articles GET /articles(.:format) articles#index POST /articles(.:format) articles#create new_article GET /articles/new(.:format) articles#new edit_article GET /articles/:id/edit(.:format) articles#edit article GET /articles/:id(.:format) articles#show PATCH /articles/:id(.:format) articles#update PUT /articles/:id(.:format) articles#update DELETE /articles/:id(.:format) articles#destroy signup GET /signup(.:format) users#new users GET /users(.:format) users#index POST /users(.:format) users#create edit_user GET /users/:id/edit(.:format) users#edit user GET /users/:id(.:format) users#show PATCH /users/:id(.:format) users#update PUT /users/:id(.:format) users#update DELETE /users/:id(.:format) users#destroy categories GET /categories(.:format) categories#index POST /categories(.:format) categories#create new_category GET /categories/new(.:format) categories#new edit_category GET /categories/:id/edit(.:format) categories#edit category GET /categories/:id(.:format) categories#show PATCH /categories/:id(.:format) categories#update PUT /categories/:id(.:format) categories#update login GET /login(.:format) session#new POST /login(.:format) session#create logout GET /logout(.:format) session#destroy controller_login POST /controller/login(.:format) session#create
问题原因与修复方案
原因分析
CategoriesControllerTest继承自ActionController::TestCase,而sign_in_as方法中使用的login_path会被当前测试的控制器(categories)作用域影响,错误生成了/login_categories这个不存在的路由。
修复方案
有两种可靠的修复方式:
直接使用登录路由的字符串路径
修改sign_in_as方法,绕过路由辅助方法的作用域问题:def sign_in_as(user) post '/login', params: { email: user.email, password: "fardeen" } end直接设置会话模拟登录(推荐)
控制器测试中无需走实际登录请求,直接在会话中设置用户ID即可,效率更高且无路由问题:def sign_in_as(user) session[:user_id] = user.id end可选:指定路由的控制器消除作用域
如果坚持使用路由辅助方法,可明确指定控制器:def sign_in_as(user) post login_path(controller: 'session'), params: { email: user.email, password: "fardeen" } end
另外,建议使用fixtures管理测试数据,或确保测试后数据被清理,避免测试间的状态干扰。
内容的提问来源于stack exchange,提问作者Fardeen
相关产品推荐
相关产品推荐

