Спецификации представления Rspec нарушены default_locale
Я недавно локализовал свое приложение Rails и добавил локаль по умолчанию 'en' (я следовал инструкциям здесь, чтобы добавить локали в мои URL). Это сломало большинство моих спецификаций; Мне удалось найти решения / обходные пути для всех из них, кроме моих спецификаций View.
Вот пример спецификации базового представления, которая нарушена, моя спецификация представления статьи:
RSpec.describe 'articles/index', type: :view do
before(:each) do
assign(:articles, [
FactoryGirl.create(:article, number: '11.22.33'),
FactoryGirl.create(:article, number: '22.33.44')
])
end
it 'renders a list of articles' do
render
end
end
Эта спецификация приводит к следующей ошибке:
1) articles/index renders a list of articles
Failure/Error: render
ActionView::Template::Error:
No route matches {:action=>"show", :controller=>"articles", :id=>nil, :locale=>#<Article id: 2, number: "11.22.33", criminal_code_id: 3, description: nil, created_at: "2015-05-25 08:58:56", updated_at: "2015-05-25 08:58:56">} missing required keys: [:id, :locale]
Похоже, есть три проблемы:
- Rspec должен использовать действие "index" вместо "show"
- Не должно быть обязательного: ключ идентификатора для действия "index"
- Локаль должна быть "en" вместо одной из статей, которые я создал.
Вот мои соответствующие маршруты:
Rails.application.routes.draw do
scope ':locale', locale: /#{I18n.available_locales.join("|")}/ do
resources :articles do
collection do
get 'custom_json', constraints: { format: :json }, defaults: { format: :json }
end
end
get "*path", to: redirect("/#{I18n.default_locale}") # handles /en/fake/path/whatever
end
get '', to: redirect("/#{I18n.default_locale}") # handles /
get '*path', to: redirect("/#{I18n.default_locale}/%{path}") # handles /not-a-locale/anything
end
Вот соответствующая часть моего контроллера приложений:
before_action :set_locale
def set_locale
I18n.locale = params[:locale] || I18n.default_locale
end
def default_url_options(options = {})
{ locale: I18n.locale }.merge options
end
И мой вид статьи находится в app/views/article /index.html.erb (в этом нет ничего необычного).
У кого-нибудь есть идеи о том, как получить спецификации View, чтобы они хорошо играли с локалями?
2 ответа
Следующее может помочь вам:
# Set locale for view specs, see https://github.com/rspec/rspec-rails/issues/255#issuecomment-2865917
class ActionView::TestCase::TestController
def default_url_options(options = {})
{locale: I18n.default_locale}
end
end
# Set locale for feature specs, see https://github.com/rspec/rspec-rails/issues/255#issuecomment-24698753
RSpec.configure do |config|
config.before(:each, type: :feature) do
default_url_options[:locale] = I18n.default_locale
end
end
Это помогло в моем случае. Тем не менее, я нахожу довольно неловким, что после стольких лет Rails I18n все еще приходится заботиться о таких вещах самостоятельно.
Вот потенциальный обходной путь, пока вы ждете, чтобы кто-то опубликовал лучший ответ:
Похоже, вы делаете link_to на своей странице индекса для каждой из ваших статей. Вызов помощника url в link_to, например article_path, где ваша спецификация может нарушаться. У меня была похожая проблема, и я не мог ее решить. Методы url_helper не работали для меня в тестовой среде так же, как в dev или prod env. В частности, в тестовой среде они не работали, если я не объявил локаль в вызове url_helper явно, используя локаль: 'en'.
Я долго оглядывался и не мог понять почему.
Поэтому я решил просто заглушить вызовы url_helpers в моей спецификации вида, как это
allow(view).to receive(:conversation_transmission_path).and_return("/")
allow(view).to receive(:edit_conversation_transmission_path).and_return("/")
это синтаксис rspec 3.2