代码之家  ›  专栏  ›  技术社区  ›  insane.dreamer

如何为功能测试(Rails)设置区域设置默认\u url\u选项

  •  11
  • insane.dreamer  · 技术社区  · 15 年前

      def default_url_options(options={})
        { :locale => I18n.locale }
      end
    

    然后,我的资源路由具有:path_prefix=“/:locale”

    但是,当涉及到我的功能测试时,生成的URL不会传递:locale,因此它们都会失败。我可以通过在测试中将区域设置添加到url中来解决这个问题,如下所示:

      get :new, :locale => 'en'
    

    但是我不希望必须手动将区域设置添加到每个功能测试中。

    是否有任何方法可以更改默认的_url _选项以包含所有测试的区域设置?

    10 回复  |  直到 15 年前
        1
  •  2
  •   prekageo    13 年前

    通过查看控制器测试用例如何生成url,似乎没有一种直接的方法让它使用defualt\u url\u选项。实际创建url的主块(在测试中)如下所示( http://github.com/rails/rails/blob/master/actionpack/lib/action_controller/test_case.rb

    private
      def build_request_uri(action, parameters)
        unless @request.env['REQUEST_URI']
          options = @controller.__send__(:rewrite_options, parameters)
          options.update(:only_path => true, :action => action)
    
          url = ActionController::UrlRewriter.new(@request, parameters)
          @request.request_uri = url.rewrite(options)
        end
      end
    

    它由process方法调用,而process方法又由get、post、head或put方法调用。获得所需内容的一种方法可能是将流程方法别名链接起来。

    class ActionController::TestCase
      def process_with_default_locale(action, parameters = nil, session = nil, flash = nil, http_method = 'GET')
        parameters = {:locale=>'en'}.merge(parameters||{})
        process_without_default_locale(action, parameters, session, flash, http_method)
      end
      alias_method_chain :process, :default_locale
    end
    

        2
  •  7
  •   Martin Carel    13 年前

    在Rails 3.1-stable分支中 process method 现在在一年之内 Behavior 模块。下面是对我有用的代码(与John Duff的答案略有不同):

    class ActionController::TestCase
    
      module Behavior
        def process_with_default_locale(action, parameters = nil, session = nil, flash = nil, http_method = 'GET')
          parameters = { :locale => I18n.default_locale }.merge( parameters || {} )
          process_without_default_locale(action, parameters, session, flash, http_method)
        end 
        alias_method_chain :process, :default_locale
      end 
    end
    

    我确保在运行规范/测试之前调用此代码。把它放在test_helper类中是一个很好的地方。

        3
  •  7
  •   schmijos Fizer Khan    4 年前

    test_helper.rb 基于 action_dispatch/testing/integration.rb

    module ActionDispatch::Integration
      class Session
        def default_url_options
          { locale: I18n.locale }
        end
      end
    end
    
        4
  •  3
  •   Chris Salzberg    11 年前

    如果有人将其用于Rails 4.0,则 process 方法已更改,所以您需要使用此更新的修补程序(基于@martin carel的答案,只需 http_method 参数移动到第二个参数):

    class ActionController::TestCase
      module Behavior
        def process_with_default_locale(action, http_method = 'GET', parameters = nil, session = nil, flash = nil)
          parameters = { :locale => I18n.locale }.merge( parameters || {} ) unless I18n.locale.nil?
          process_without_default_locale(action, http_method, parameters, session, flash)
        end
        alias_method_chain :process, :default_locale
      end
    end
    

    希望这能帮助任何陷入这个问题的人。

        5
  •  3
  •   Roman Malkevych    5 年前

    Rails.application.configure do
      # ... other config ...
    
      routes.default_url_options[:locale] = :en
    end
    

    轨道工程5.1.4

        6
  •  2
  •   django09    8 年前

    alias_method_chain deprecated in Rails 5 ,似乎行为过程方法已经改变。

    这是我对上面Martin Carel的答案的修改,改编为Rails 5。

    RSpec.configure do |config|
      module ActionController
        class TestCase
          module Behavior
            module LocaleParameter
              def process(action, parameters = {params: {}})
                unless I18n.locale.nil?
                  parameters[:params][:locale] = I18n.locale
                end
    
                super(action, parameters)
              end
            end
    
            prepend Behavior::LocaleParameter
    
          end
        end
      end
    end
    

    我绝对不是Rails或Ruby方面的专家,所以如果这个答案中有什么地方可以改进,请告诉我,我会改变它。

        7
  •  1
  •   Gur Dotan    14 年前

    我因为黄瓜测试不及格而遇到了这个问题。 我使用区域设置作为url中的参数,即。 http://mysite.com/home?locale=he

    我要做的是在测试过程中通过定义默认的\u url\u选项(取决于我使用的环境),从url中删除所有与语言环境相关的内容:

      # app/controllers/application_controller.rb
      def default_url_options(options={})
        logger.debug "default_url_options is passed options: #{options.inspect}\n"
        ENV["RAILS_ENV"] != "cucumber" ? { :locale => I18n.locale } : {}
      end
    
        8
  •  1
  •   Paul McMahon    14 年前

    setup :set_default_locale 
    
    def set_default_locale
      def @request.query_parameters
        {:locale => "en"}.merge(@query_parameters)
      end
    end
    

    此解决方案的优点是,它意味着您只能将默认语言环境参数应用于某些测试用例,因此您可以测试重定向策略本身。

        9
  •  1
  •   Lauri Kolmonen panmari    7 年前

    Ruby 5.1再次改变了一切。以下是对我有效的方法:

    class ActionController::TestCase
      module Behavior
        module LocaleParameter
          def process(action, params: {}, **args)
            # Locale parameter must be a string
            params[:locale] = I18n.locale.to_s
            super(action, params: params, **args)
          end
        end
      end
      prepend Behavior::LocaleParameter
    end
    
        10
  •  0
  •   Balint Erdi    14 年前

    通过集成测试,我发现上面的monkey补丁需要有所不同,这对我来说很有用(Rails 2.3.4):

    class ActionController::Integration::Session
      def url_for_with_default_locale(options)
        options = { :locale => 'en' }.merge(options)
        url_for_without_default_locale(options)
      end
      alias_method_chain :url_for, :default_locale
    end