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

如何在ActionDispatch::IntegrationTest中使用default_url_options及path_params?

让IntegrationTest调用default_url_options并使用path_params的方法

你遇到的问题是因为默认情况下,IntegrationTest中的路由辅助方法(比如post_url)会使用全局路由上下文(Rails.application.routes)生成URL,不会自动调用测试类实例的default_url_options方法。要解决这个问题,你需要让路由辅助方法使用测试实例的上下文,具体有两种可行方案:

方案一:集成ActionDispatch::Routing::UrlFor模块

在测试类中集成ActionDispatch::Routing::UrlFor模块,并指定路由为应用路由,这样路由辅助方法会使用测试实例的default_url_options:

class BlogControllerTest < ActionDispatch::IntegrationTest
  # 引入UrlFor模块,让路由辅助方法使用实例上下文
  include ActionDispatch::Routing::UrlFor

  setup do
    @blog = blogs(:with_posts).first
    @post = @blog.posts.first
    # 指定使用应用的路由规则
    self.routes = Rails.application.routes
  end

  test "accessing a post with default_url_options" do
    get post_url(@post)
    assert_response :success
  end

  # 该测试可以保留,作为对比
  test "accessing a post" do
    get post_url(@post, blog_id: @blog.id)
    assert_response :success
  end

  private

    def default_url_options(options = {})
      # 合并父类的默认选项,避免覆盖必要配置
      super.merge(path_params: { blog_id: @blog.id })
    end    
end

方案二:临时修改全局路由的默认选项

如果不想引入额外模块,可以在setup中临时修改全局路由的default_url_options,并在teardown中恢复原值,避免影响其他测试:

class BlogControllerTest < ActionDispatch::IntegrationTest
  setup do
    @blog = blogs(:with_posts).first
    @post = @blog.posts.first
    # 保存原始默认选项,用于测试后恢复
    @original_defaults = Rails.application.routes.default_url_options.dup
    # 设置全局路由的path_params默认值
    Rails.application.routes.default_url_options[:path_params] = { blog_id: @blog.id }
  end

  teardown do
    # 恢复原始默认选项,避免污染其他测试
    Rails.application.routes.default_url_options = @original_defaults
  end

  test "accessing a post with default_url_options" do
    get post_url(@post)
    assert_response :success
  end

  test "accessing a post" do
    get post_url(@post, blog_id: @blog.id)
    assert_response :success
  end
end

说明

方案一更符合测试实例的隔离性,每个测试实例可以有自己的default_url_options配置;方案二更简洁,但需要注意全局状态的恢复,避免影响其他测试用例。两种方案都能让url_for自动使用path_params中的blog_id,无需手动在路由辅助方法中传递参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 06:48:35