Rspec 使用可选的语言环境路径查看测试
Rspec view test with optional locale path
我的路线中有一个可选的语言环境参数。
# config/routes.rb
scope '(:locale)' do
resources :orders
resources :line_items
resources :carts
root 'store#index', as: 'store_index', via: :all
end
# config/initializers/i18n.rb
#encoding: utf-8
I18n.default_locale = :en
LANGUAGES = [
['English', 'en'],
["Español".html_safe, 'es']
]
如果我想像这样测试我的观点,
# /spec/views/carts/edit.html.erb_spec.rb
require 'rails_helper'
RSpec.describe "carts/edit", type: :view do
let(:cart) { create(:cart) }
before(:each) do
assign(:cart, cart)
end
it "renders the edit cart form" do
render
assert_select "form[action=?][method=?]", cart_path(cart), "post" do
end
end
end
我收到一个错误
/Users/burak/.rvm/rubies/ruby-2.7.3/bin/ruby -I/Users/burak/.rvm/gems/ruby-2.7.3/gems/rspec-core-3.10.1/lib:/Users/burak/.rvm/gems/ruby-2.7.3/gems/rspec-support-3.10.2/lib /Users/burak/.rvm/gems/ruby-2.7.3/gems/rspec-core-3.10.1/exe/rspec spec/views/carts/edit.html.erb_spec.rb
F
Failures:
1) carts/edit renders the edit cart form
Failure/Error: <%= form_with(model: cart) do |form| %>
ActionView::Template::Error:
No route matches {:action=>"show", :controller=>"carts", :format=>nil, :locale=>#<Cart id: 1252, created_at: "2021-04-27 13:45:09.842106000 +0000", updated_at: "2021-04-27 13:45:09.842106000 +0000">}, missing required keys: [:id]
Did you mean? cart_url
carts_url
carts_path
new_cart_url
# ./app/views/carts/_form.html.erb:1:in `_app_views_carts__form_html_erb__2203507052991398875_16560'
# ./app/views/carts/edit.html.erb:3:in `_app_views_carts_edit_html_erb___4312857554407673387_16540'
# ./spec/views/carts/edit.html.erb_spec.rb:11:in `block (2 levels) in <top (required)>'
# ------------------
# --- Caused by: ---
# ActionController::UrlGenerationError:
# No route matches {:action=>"show", :controller=>"carts", :format=>nil, :locale=>#<Cart id: 1252, created_at: "2021-04-27 13:45:09.842106000 +0000", updated_at: "2021-04-27 13:45:09.842106000 +0000">}, missing required keys: [:id]
# Did you mean? cart_url
# carts_url
# carts_path
# new_cart_url
# ./app/views/carts/_form.html.erb:1:in `_app_views_carts__form_html_erb__2203507052991398875_16560'
Finished in 0.02277 seconds (files took 0.60597 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/views/carts/edit.html.erb_spec.rb:10 # carts/edit renders the edit cart form
据我所知,这是因为我的购物车对象通过 :locale
关键字传递到某个地方。如果我在我的 _form
部分中显式地将 URL 传递给 form_with
,则错误会消失,但随后会破坏其他一些测试。我该如何解决这个问题?
这是必要的部分和视图。
# app/views/carts/edit.html.erb
<h1>Editing Cart</h1>
<%= render 'form', cart: @cart %>
<%= link_to 'Show', @cart %> |
<%= link_to 'Back', carts_path %>
# app/views/carts/_form.html.erb
<%= form_with(model: cart) do |form| %>
<% if cart.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(cart.errors.count, "error") %> prohibited this cart from being saved:</h2>
<ul>
<% cart.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
因此您的表单要指向的 URL 的路由是(在您将从 rails routes
中看到的格式中):
(/:locale)/carts/:id(.:format)
看起来正在发生的事情是,当您的视图规范正在呈现时,它会调用 cart_path(cart)
来构建表单的 action
属性。发生的事情是辅助方法 cart_path
尝试从左到右填充路径的参数化部分,它使用 cart
尝试填充 :locale
段而不是:id
段。
在 rails server
中的控制器操作呈现的上下文中,您不会看到这种情况发生,因为控制器具有 locale
具有默认值的概念,因此它理解 cart
代表路径的第二个 :id
部分。
如果你想确保你的视图在单独测试时表现相似,那么你可以在你的路由文件中添加一个默认值:
scope '(:locale)', defaults: { locale: 'en' } do
...
并在您的 config/environments/test.rb
中添加另一个默认值:
Rails.application.configure do
# ...
routes.default_url_options[:locale] = 'en'
end
在routes.rb
中设置默认值将允许您的视图文件正确生成有效路径;添加 default_url_options
意味着您可以在视图规范中写入 cart_path(cart)
,它会知道默认使用 'en' 作为语言环境。没有它,您必须断言操作路径是 cart_path(cart, locale: 'en')
.
我的路线中有一个可选的语言环境参数。
# config/routes.rb
scope '(:locale)' do
resources :orders
resources :line_items
resources :carts
root 'store#index', as: 'store_index', via: :all
end
# config/initializers/i18n.rb
#encoding: utf-8
I18n.default_locale = :en
LANGUAGES = [
['English', 'en'],
["Español".html_safe, 'es']
]
如果我想像这样测试我的观点,
# /spec/views/carts/edit.html.erb_spec.rb
require 'rails_helper'
RSpec.describe "carts/edit", type: :view do
let(:cart) { create(:cart) }
before(:each) do
assign(:cart, cart)
end
it "renders the edit cart form" do
render
assert_select "form[action=?][method=?]", cart_path(cart), "post" do
end
end
end
我收到一个错误
/Users/burak/.rvm/rubies/ruby-2.7.3/bin/ruby -I/Users/burak/.rvm/gems/ruby-2.7.3/gems/rspec-core-3.10.1/lib:/Users/burak/.rvm/gems/ruby-2.7.3/gems/rspec-support-3.10.2/lib /Users/burak/.rvm/gems/ruby-2.7.3/gems/rspec-core-3.10.1/exe/rspec spec/views/carts/edit.html.erb_spec.rb
F
Failures:
1) carts/edit renders the edit cart form
Failure/Error: <%= form_with(model: cart) do |form| %>
ActionView::Template::Error:
No route matches {:action=>"show", :controller=>"carts", :format=>nil, :locale=>#<Cart id: 1252, created_at: "2021-04-27 13:45:09.842106000 +0000", updated_at: "2021-04-27 13:45:09.842106000 +0000">}, missing required keys: [:id]
Did you mean? cart_url
carts_url
carts_path
new_cart_url
# ./app/views/carts/_form.html.erb:1:in `_app_views_carts__form_html_erb__2203507052991398875_16560'
# ./app/views/carts/edit.html.erb:3:in `_app_views_carts_edit_html_erb___4312857554407673387_16540'
# ./spec/views/carts/edit.html.erb_spec.rb:11:in `block (2 levels) in <top (required)>'
# ------------------
# --- Caused by: ---
# ActionController::UrlGenerationError:
# No route matches {:action=>"show", :controller=>"carts", :format=>nil, :locale=>#<Cart id: 1252, created_at: "2021-04-27 13:45:09.842106000 +0000", updated_at: "2021-04-27 13:45:09.842106000 +0000">}, missing required keys: [:id]
# Did you mean? cart_url
# carts_url
# carts_path
# new_cart_url
# ./app/views/carts/_form.html.erb:1:in `_app_views_carts__form_html_erb__2203507052991398875_16560'
Finished in 0.02277 seconds (files took 0.60597 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/views/carts/edit.html.erb_spec.rb:10 # carts/edit renders the edit cart form
据我所知,这是因为我的购物车对象通过 :locale
关键字传递到某个地方。如果我在我的 _form
部分中显式地将 URL 传递给 form_with
,则错误会消失,但随后会破坏其他一些测试。我该如何解决这个问题?
这是必要的部分和视图。
# app/views/carts/edit.html.erb
<h1>Editing Cart</h1>
<%= render 'form', cart: @cart %>
<%= link_to 'Show', @cart %> |
<%= link_to 'Back', carts_path %>
# app/views/carts/_form.html.erb
<%= form_with(model: cart) do |form| %>
<% if cart.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(cart.errors.count, "error") %> prohibited this cart from being saved:</h2>
<ul>
<% cart.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
因此您的表单要指向的 URL 的路由是(在您将从 rails routes
中看到的格式中):
(/:locale)/carts/:id(.:format)
看起来正在发生的事情是,当您的视图规范正在呈现时,它会调用 cart_path(cart)
来构建表单的 action
属性。发生的事情是辅助方法 cart_path
尝试从左到右填充路径的参数化部分,它使用 cart
尝试填充 :locale
段而不是:id
段。
在 rails server
中的控制器操作呈现的上下文中,您不会看到这种情况发生,因为控制器具有 locale
具有默认值的概念,因此它理解 cart
代表路径的第二个 :id
部分。
如果你想确保你的视图在单独测试时表现相似,那么你可以在你的路由文件中添加一个默认值:
scope '(:locale)', defaults: { locale: 'en' } do
...
并在您的 config/environments/test.rb
中添加另一个默认值:
Rails.application.configure do
# ...
routes.default_url_options[:locale] = 'en'
end
在routes.rb
中设置默认值将允许您的视图文件正确生成有效路径;添加 default_url_options
意味着您可以在视图规范中写入 cart_path(cart)
,它会知道默认使用 'en' 作为语言环境。没有它,您必须断言操作路径是 cart_path(cart, locale: 'en')
.