在我的application_controller中,我有以下设置来包含url_for生成的所有路径的语言环境:
def default_url_options(options={})
{ :locale => I18n.locale }
end
我的资源路线有一个:path_prefix =“/:locale”
在网站上正常工作。
但是当涉及到我的功能测试时,:locale不会与生成的url一起传递,因此它们都会失败。我可以通过在我的测试中将语言环境添加到url来解决它,如下所示:
get :new, :locale => 'en'
但我不想手动将语言环境添加到每个功能测试中。
我尝试将default_url_options def添加到test_helper,但似乎没有效果。
有什么方法可以更改default_url_options以包含我所有测试的区域设置?
感谢。
答案 0 :(得分:7)
在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
我确保在运行specs / tests之前调用此代码。放置它的好地方是在test_helper类中。
答案 1 :(得分:6)
对于Rails 5,我找到了这个简单的解决方案
在test_helper.rb
基于action_dispatch/testing/integration.rb
module ActionDispatch::Integration
class Session
def default_url_options
{ locale: I18n.locale }
end
end
end
答案 2 :(得分:3)
如果有人在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
希望能帮助任何人解决这个问题。
答案 3 :(得分:2)
查看控制器测试用例如何生成url,似乎没有直接的方法让它使用defualt_url_options。实际执行url 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或put方法调用。可能获得您正在寻找的内容的一种方法可能是alias_chain过程方法。
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
你想把它放在我认为的TestCase类之外的测试帮助器中。让我知道它对你有用,我还没有真正测试过,所以我们会看到。
答案 4 :(得分:2)
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的专家,所以如果在这个答案中可以改进一些内容,请告诉我,我会改变它。
答案 5 :(得分:1)
我遇到了一个失败的黄瓜测试问题。 我在网址中使用locales作为参数,即http://mysite.com/home?locale=he
我要做的是通过根据我使用的环境定义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
答案 6 :(得分:1)
我已经提出了一个针对这个问题的侵入性较小的解决方案。
setup :set_default_locale
def set_default_locale
def @request.query_parameters
{:locale => "en"}.merge(@query_parameters)
end
end
此解决方案的优点是,它意味着您只能将默认语言环境参数应用于某些测试用例,因此您可以测试,例如,重定向策略本身。
答案 7 :(得分: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
答案 8 :(得分: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
答案 9 :(得分:0)
我尝试了很多例子,但是只有这个例子对我有帮助。简洁明了。将此代码段添加到test.rb:
Rails.application.configure do
# ... other config ...
routes.default_url_options[:locale] = :en
end
在Rails 5.1.4上运行