You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

首次在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 03:15:36