首次在Rails Engine中使用RSpec遇路由匹配错误求助
Rails Engine中RSpec单元测试路由匹配问题排查与修复
我首次在Rails Engine中使用RSpec进行单元测试时,遇到了无法解决的路由匹配问题,以下是相关代码、报错信息及修复方案:
路由配置
Community::Questions::Engine.routes.draw do resources :questions, path: '/', only: [:index, :show, :create, :destroy, :update] do resources :answers, path: '/answers', only: [:index, :show, :create, :destroy, :update] resources :search, path: '/all', only: [:index] end end
控制器代码
module Community::Questions class QuestionsController < ApplicationController skip_before_action :verify_authenticity_token before_action :authenticate_user!, only: %i[create update destroy] def index questions = Community::Question.last(5) render_json(questions) end end end
测试代码
require "rails_helper" RSpec.describe Community::Questions::QuestionsController, type: :controller do describe "GET index" do it "returns a 200" do get :index expect(response).to have_http_status(:ok) end end end
报错信息
Failures: 1) Community::Questions::QuestionsController GET index returns a 200 Failure/Error: get :index ActionController::UrlGenerationError: No route matches {:action=>"index", :controller=>"community/questions/questions"} # ./spec/community/questions_controller_spec.rb:6:in `block (3 levels) in <top (required)>' Finished in 0.02578 seconds (files took 1.31 seconds to load) 1 example, 1 failure Failed examples: rspec ./spec/community/questions_controller_spec.rb:5 # Community::Questions::QuestionsController GET index returns a 200
问题原因
RSpec默认会在主应用的路由集合中查找匹配项,但你的控制器属于Rails Engine,对应的路由仅存在于该Engine的路由集合内,因此无法找到对应路由规则。
修复方案
方案一:指定测试使用Engine的路由集合
在测试代码中明确声明使用目标Engine的路由集合:
require "rails_helper" RSpec.describe Community::Questions::QuestionsController, type: :controller do # 指定当前测试使用Engine的路由 routes { Community::Questions::Engine.routes } describe "GET index" do it "returns a 200" do get :index expect(response).to have_http_status(:ok) end end end
方案二:调用请求时指定Engine路由标识
在get方法中添加use_route参数,指定Engine的路由命名(通常为Engine类名的下划线形式,即community_questions):
require "rails_helper" RSpec.describe Community::Questions::QuestionsController, type: :controller do describe "GET index" do it "returns a 200" do get :index, use_route: :community_questions expect(response).to have_http_status(:ok) end end end
验证路由(可选)
可以通过以下命令查看Engine生成的所有路由,确认路由与控制器的对应关系:
bundle exec rake community_questions:routes
内容的提问来源于stack exchange,提问作者Ramadhani Baharzah
相关产品推荐
相关产品推荐

