路由错误 I18n 和 rspec
Route error I18n and rspec
在应用程序中,我使用 gem "I18n" 进行国际化。一切正常,但在验收测试中,我收到一个错误:
Failure/Error: expect(current_path).to eq profile_path
expected: "/profile"
got: "/en/profile"
(compared using ==)
测试:
describe 'User go to profile' do
before do
page.driver.header 'Accept-Language', locale
I18n.locale = locale
sign_in (user)
end
context 'locale EN' do
let(:locale) { :en }
scenario 'and view see profile page' do
visit profile_path
expect(current_path).to eq profile_path
end
end
end
现场一切正常。我该如何解决?
当使用支持 JS 的驱动程序(capybara-webkit 是)时,Capybara 操作异步发生。这意味着对访问的调用可能 return 在浏览器的 URL 实际发生变化之前,这也是为什么大多数水豚动作都有内置的等待行为。在这种情况下,您可能会在浏览器从旧路径更改为新路径之前获得 current_path。有几个解决方案
如果使用 Capybara 2.5+ 更改为使用具有内置等待行为的 have_current_path 匹配器
期待(页面).to have_current_path(profile_path)
为页面上应有的内容添加内容检查 - 将触发等待行为并确保在获取 current_path
[=26= 之前加载页面]
访问后添加一两秒的休眠,这将使浏览器有时间更改到新路径
显然 #1 是更好的解决方案,除非你有某些原因不能使用 Capybara 2.5+
既然你说问题只出现在 RSpec 测试中并且应用程序运行良好,那么我假设你希望 URL 的形式为 /:locale/profile(.:format)
.因此,如果您的应用程序中有类似以下路由范围的内容...
config/routes.rb
scope ":locale", locale: /#{I18n.available_locales.join("|")}/ do
get 'profile', to: 'users#profile'
# other routes
end
...并且您的控制器中有如下内容(可能是 ApplicationController
),它会自动将 locale
注入 url 选项...
def url_options
{ locale: I18n.locale }.merge(super)
end
(以上也可以是 default_url_options
作为 的覆盖)
...然后,您还需要将 locale
作为参数传递给规范中的路径:
describe 'User go to profile' do
before do
page.driver.header 'Accept-Language', locale
I18n.locale = locale
sign_in (user)
end
context 'locale EN' do
let(:locale) { :en }
scenario 'and view see profile page' do
visit profile_path
expect(current_path).to eq profile_path(locale: locale)
end
end
end
假设以上是正确的,您甚至可以在 rails 控制台中对此进行测试并(可能)获得类似于以下内容的输出:
irb> app.profile_path
ActionController::UrlGenerationError: No route matches {:action=>"profile", :controller=>"users"} missing required keys: [:locale]
irb> app.profile_path(locale: :en)
"/en/profile"
在应用程序中,我使用 gem "I18n" 进行国际化。一切正常,但在验收测试中,我收到一个错误:
Failure/Error: expect(current_path).to eq profile_path
expected: "/profile"
got: "/en/profile"
(compared using ==)
测试:
describe 'User go to profile' do
before do
page.driver.header 'Accept-Language', locale
I18n.locale = locale
sign_in (user)
end
context 'locale EN' do
let(:locale) { :en }
scenario 'and view see profile page' do
visit profile_path
expect(current_path).to eq profile_path
end
end
end
现场一切正常。我该如何解决?
当使用支持 JS 的驱动程序(capybara-webkit 是)时,Capybara 操作异步发生。这意味着对访问的调用可能 return 在浏览器的 URL 实际发生变化之前,这也是为什么大多数水豚动作都有内置的等待行为。在这种情况下,您可能会在浏览器从旧路径更改为新路径之前获得 current_path。有几个解决方案
如果使用 Capybara 2.5+ 更改为使用具有内置等待行为的 have_current_path 匹配器
期待(页面).to have_current_path(profile_path)
为页面上应有的内容添加内容检查 - 将触发等待行为并确保在获取 current_path
[=26= 之前加载页面]访问后添加一两秒的休眠,这将使浏览器有时间更改到新路径
显然 #1 是更好的解决方案,除非你有某些原因不能使用 Capybara 2.5+
既然你说问题只出现在 RSpec 测试中并且应用程序运行良好,那么我假设你希望 URL 的形式为 /:locale/profile(.:format)
.因此,如果您的应用程序中有类似以下路由范围的内容...
config/routes.rb
scope ":locale", locale: /#{I18n.available_locales.join("|")}/ do
get 'profile', to: 'users#profile'
# other routes
end
...并且您的控制器中有如下内容(可能是 ApplicationController
),它会自动将 locale
注入 url 选项...
def url_options
{ locale: I18n.locale }.merge(super)
end
(以上也可以是 default_url_options
作为
...然后,您还需要将 locale
作为参数传递给规范中的路径:
describe 'User go to profile' do
before do
page.driver.header 'Accept-Language', locale
I18n.locale = locale
sign_in (user)
end
context 'locale EN' do
let(:locale) { :en }
scenario 'and view see profile page' do
visit profile_path
expect(current_path).to eq profile_path(locale: locale)
end
end
end
假设以上是正确的,您甚至可以在 rails 控制台中对此进行测试并(可能)获得类似于以下内容的输出:
irb> app.profile_path
ActionController::UrlGenerationError: No route matches {:action=>"profile", :controller=>"users"} missing required keys: [:locale]
irb> app.profile_path(locale: :en)
"/en/profile"