通过 default_url_options 为 Rails 测试设置语言环境(Rails 6 及更新版本)

Set locale via default_url_options for Rails tests (Rails 6 and newer)

是否有可靠的方法通过 default_url_options 为 Rails 全局测试(控制器和系统测试)设置语言环境,而无需手动将语言环境传递给 url 助手?

在 Rails 6.0.1 之前,这曾经有效:

# Set locale via default_url_options
class ActionDispatch::Routing::RouteSet
  def default_url_options(options = {})
    { locale: I18n.locale }.merge options
  end
end

按照此 Rails issue,您可以在没有猴子补丁的情况下访问 default_url_options

ActionDispatch::IntegrationTest.app.default_url_options[:locale] = I18n.locale

但是我建议每次都手动传递语言环境参数。

我在一个应用程序中遇到了同样的问题,最终在所有测试中手动设置了参数。第一次很乏味,但它最终使所有调用更加清晰,并有助于减少对专门用于测试套件的代码的依赖。

无论如何,控制器测试应该尊重 ApplicationController 中的 default_url_options 集。

要为系统测试使用默认语言环境,对于 Rails 6,将此片段添加到 test_helper.rb 文件就足够了,如问题所述:

class ActionDispatch::Routing::RouteSet
  def default_url_options(options = {})
    { locale: I18n.locale }.merge options
  end
end

对于 Rails 6.0.1 和 6.0.2,需要将此野兽添加到 application_system_test_case.rb 文件中:

  # See actionpack/lib/action_dispatch/system_test_case.rb
  def initialize(*)
    super
    @proxy_route = if ActionDispatch.test_app
      Class.new do
        include ActionDispatch.test_app.routes.url_helpers
        include ActionDispatch.test_app.routes.mounted_helpers

        def url_options
          default_url_options.merge(host: Capybara.app_host, locale: I18n.locale)
        end
      end.new
    else
      nil
    end
  end