2009-12-31 28 views
9

在我application_controller,我有下面的一組包括由url_for生成的所有路徑的語言環境:如何設置功能測試(Rails)的區域default_url_options

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

我的資源路徑則有:串流中刪除= 「/:locale」

在網站上正常工作。

但是,當涉及到我的功能測試中,:區域不與生成的URL傳遞,因此他們都失敗。我可以通過添加區域設置的URL在我的測試中,像這樣繞過它:

get :new, :locale => 'en' 

但我不希望有區域設置手動添加到每一個功能測試。

我嘗試添加了default_url_options DEF以上test_helper,但它似乎沒有任何效果。

有沒有什麼辦法可以改變default_url_options以包括了所有的考試的語言環境?

謝謝。

回答

2

通過控制器測試情況如何生成的URL看似乎有不被直接的辦法把它使用defualt_url_options。實際執行網址creationg(在測試)主塊看起來像這樣(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 

這得到由後者又由GET,POST,HEAD調用,或把工藝方法稱爲方法。一種可能得到你正在尋找的方法可能是對過程方法進行alias_chain。

​​

你會想把它放到TestCase類之外的測試助手中,我想。讓我知道它如何爲你工作,我沒有真正測試過,所以我們會看到。

+0

謝謝,約翰。這解決了上面的具體情況,似乎很好! 它似乎並沒有解決的問題是TestCase如何解釋命名路由,無論它們是在測試本身中,還是在應用程序中使用。例如,如果我有一個測試: redirect_to homepage_url 和homepath_url需要語言環境(map.homepage'/:locale',:controller =>'home'),當運行測試時出現錯誤, URL要求不滿意(缺少「區域設置」)。再次,應用程序運行良好,因爲default_url_options負責添加區域設置。有什麼辦法解決這個問題? – 2010-01-01 03:27:48

+0

我想補充一句,如果這只是測試本身的一個問題,那就不會那麼糟糕。無論何時在測試中使用命名路由,我都可以添加區域設置。但問題是,無論何時在我的應用程序中使用命名路由時,它也會生成一個錯誤(並且我不希望每次都改變所有這些或指定區域設置,這樣我的測試將運行)。 – 2010-01-01 03:34:22

+0

啊,我沒有意識到它也發生在你的應用中。我剛剛遇到了一張燈塔,可能會幫助你一點點(似乎仍然是一個問題,但有一些解決辦法)https://rails.lighthouseapp.com/projects/8994/tickets/1251-default_url_options-cant -be-used-named-routes – 2010-01-02 01:23:45

0

隨着集成測試,我發現,上面的猴子補丁需要是不同的,這是對我工作(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 
1

我就遇到了這個問題,一個失敗的黃瓜測試。 我使用的語言環境中的URL參數,即http://mysite.com/home?locale=he

我要做的,以應付這是從URL測試期間根據我的使用環境定義default_url_options刪除所有區域設置相關的東西:

# 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 
+0

我不確定這是否暴露了某些邊緣情況,但對我來說這似乎是一種優雅的解決方案。 – Jaryl 2011-06-03 04:05:27

1

我想出了一個針對這個問題的較少侵入性的解決方案。

setup :set_default_locale 

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

這種解決方案的優點是,它意味着你只能在默認的語言環境參數適用於某些測試用例,這樣你就可以測試,例如,重定向策略本身。

7

在軌道3.1穩定分支,所述process method現在是Behavior模塊內。因此,這裏是爲我工作的代碼(從約翰·達芙的回答略有不同):

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類中。

+0

Martin Carel在http://www.ruby-forum.com/topic/3448797上列出了這個方法,他還添加了另一個方法:'module ActionDispatch :: Assertions :: RoutingAssertions def assert_recognizes_with_default_locale(expected_options,path, extras = { },message = nil) expected_options = {:locale => I18n.default_locale.to_s }。合併(expected_options || {}) assert_recognizes_without_default_locale(expected_options,路徑, 演員,消息) 端 alias_method_chain:assert_recognizes,:DEFAULT_LOCALE end' – wintersolutions 2012-02-06 15:14:54

+1

我還表示,修改'assert_recognizes'方法是一個** **欺騙。事實上,我認爲不要模仿你正在測試的代碼(就像在'Behavior'模塊中添加一個方法的情況一樣),而是破解你的測試工具。 – 2012-02-08 14:22:55

3

如果任何人使用此使用Rails 4.0,在process方法參數的順序發生了變化,所以你需要使用這個更新補丁(基於@馬丁 - 卡樂的回答,只是用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 

希望幫助任何人停留在這個問題上。

2

alias_method_chaindeprecated in Rails 5,它似乎行爲過程方法已更改。

這裏是我的上述馬丁卡雷爾的回答修改,適應了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的專家,所以如果事情能在這個答案得到改善,讓我知道,我會改變它。

+0

是的!這是解決方案,並添加到每個測試我想要定義一個不同的區域'before:context do I18n.locale =:ca end'我可以測試每個circunstance所需的任何區域設置。使用rails 5.1.4.rc1 – 2017-11-22 11:16:40

+0

我加了'if參數[:params] .nil?除非I18n.locale.nil?....'''''''params] = {} end'''以避免參數崩潰 – 2017-11-22 13:04:46

3

對於導軌5,我發現這個簡單的解決方案 在test_helper.rb中

module ActionDispatch::Integration 
    class Session 
    def default_url_options 
     { locale: I18n.locale } 
    end 
    end 
end 
+0

感謝您的回答,它爲我工作。雖然我想知道是否有任何方法使用ApplicationController中的自定義default_url_options,因爲編寫兩次相同的配置沒有任何意義。 – afaundez 2017-07-29 22:18:51

+0

這在Rails 5.1.4中適用於我。 – taylorthurlow 2018-03-01 22:31:49

1

觀光用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 
相關問題