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

RSpec测试Rails嵌套路由报错:ActionController::RoutingError求助

嘿,作为Rails和测试领域的新手,遇到这种路由匹配问题太正常了,咱们一步步拆解解决~

先揪出你测试里的几个核心问题

  1. 误用了Capybara的visit方法:visit是给系统/功能测试(模拟用户浏览器操作)用的,而你写的是控制器测试,应该用Rails内置的get/post这类直接调用控制器动作的方法,用visit肯定会报错。
  2. 路由辅助方法的参数传递有误:你的嵌套路由client_source_recipes需要父级资源的参数,辅助方法的调用格式得搞对。
  3. 对get方法的参数格式理解有偏差:控制器测试里的get方法用法和你尝试的有些不一样。

给你两种正确的测试写法

写法一:直接指定动作名(控制器测试首选,更清晰)

这种方式明确告诉测试你要调用recipes#index动作,把路由需要的所有参数放到params哈希里:

RSpec.describe RecipesController, :type => :controller do
  # 一定要确保每个测试前都执行登录!
  before(:each) { login_user }

  let(:client) { create :client }
  let(:source) { create :source, warehouse_id: 1, client_id: client.id }
  let(:valid_attributes) { { name: "name", source_id: source.id } }
  let(:valid_session) { {"warden.user.user.key" => session["warden.user.user.key"]} }

  describe "GET #index" do
    it "assigns all recipes as @recipes" do
      recipe = Recipe.create! valid_attributes
      # 正确的get调用方式
      get :index, 
          params: { 
            client_id: client.id, 
            source_id: source.id, 
            locale: 'cs' 
          }, 
          session: valid_session
      expect(assigns(:recipes)).to eq([recipe])
    end
  end
end

写法二:使用路由辅助方法

如果你想用路由辅助方法client_source_recipes_path,要注意它需要接收父级资源(client和source,或者它们的ID),额外参数比如locale可以作为哈希传递:

# 用对象传递参数
get client_source_recipes_path(client, source, locale: 'cs'), session: valid_session

# 或者用ID传递参数
get client_source_recipes_path(client.id, source.id, locale: 'cs'), session: valid_session

额外排查点(新手容易踩的坑)

  1. 确认登录逻辑生效:你的valid_session依赖登录后的session数据,一定要用before(:each) { login_user }确保每个测试前都完成登录,不然session为空可能导致奇怪的路由报错。
  2. 验证资源关联正确性:可以加个小断言确认source确实属于client:
    expect(source.client).to eq(client)
    
  3. 确认路由定义正确:在终端运行rails routes | grep client_source_recipes,检查输出和你给出的路由配置完全一致。

为什么你之前的写法会报错?

  • 用visit的写法:控制器测试上下文里没有visit方法(这是Capybara专属),强行调用肯定会触发路由/方法不存在的错误。
  • get client_source_recipes_path, params: { ... }:这种写法矛盾了——如果第一个参数是路由辅助方法生成的URL,就不需要再单独传params哈希,参数应该直接传给路由辅助方法。

内容的提问来源于stack exchange,提问作者ARK

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:52:21