【问题标题】:Rails 3 and rspec and i18n - correct test for controller doesn't work (it fails)Rails 3 和 rspec 和 i18n - 控制器的正确测试不起作用(失败)
【发布时间】:2012-09-04 00:30:43
【问题描述】:

我有这样的控制器

class StatsController < ApplicationController
  def users_in_system
    @users = User.all
  end
end

路线

  scope ":locale", locale: /#{I18n.available_locales.join("|")}/ do
    devise_for :users, :skip => [:registrations]                                          
    as :user do
      get 'users/edit' => 'devise/registrations#edit', :as => 'edit_user_registration'    
      put 'users' => 'devise/registrations#update', :as => 'user_registration'            
      get '/users/sign_out' => 'devise/sessions#destroy'                                  
    end

    match '/users_list', :to => 'stats#users_in_system'
    match '/about', :to => 'pages#about'
    root :to => 'pages#home'
  end

  match '*path', to: redirect("/#{I18n.default_locale}/%{path}"), constraints: lambda { |req| !req.path.starts_with? "/#{I18n.default_locale}/" }
  match '', to: redirect("/#{I18n.default_locale}")

Rake routes:

      new_user_session GET    /:locale/users/sign_in(.:format)       devise/sessions#new {:locale=>/en|ru/}
          user_session POST   /:locale/users/sign_in(.:format)       devise/sessions#create {:locale=>/en|ru/}
  destroy_user_session DELETE /:locale/users/sign_out(.:format)      devise/sessions#destroy {:locale=>/en|ru/}
         user_password POST   /:locale/users/password(.:format)      devise/passwords#create {:locale=>/en|ru/}
     new_user_password GET    /:locale/users/password/new(.:format)  devise/passwords#new {:locale=>/en|ru/}
    edit_user_password GET    /:locale/users/password/edit(.:format) devise/passwords#edit {:locale=>/en|ru/}
                       PUT    /:locale/users/password(.:format)      devise/passwords#update {:locale=>/en|ru/}
edit_user_registration GET    /:locale/users/edit(.:format)          devise/registrations#edit {:locale=>/en|ru/}
     user_registration PUT    /:locale/users(.:format)               devise/registrations#update {:locale=>/en|ru/}
        users_sign_out GET    /:locale/users/sign_out(.:format)      devise/sessions#destroy {:locale=>/en|ru/}
            users_list        /:locale/users_list(.:format)          stats#users_in_system {:locale=>/en|ru/}
                 about        /:locale/about(.:format)               pages#about {:locale=>/en|ru/}
                  root        /:locale(.:format)                     pages#home {:locale=>/en|ru/}
                              /*path(.:format)                       :controller#:action
                              /                                      :controller#:action

我想为控制器编写测试。所以我尝试了spec

require 'spec_helper'

describe StatsController do
  render_views

  before(:each){ @user = FactoryGirl.create( :user ) }

  describe "GET 'users_in_system'" do
    describe "for non-signed users" do
      it "should deny access" do
        get :users_in_system
        #...
      end
    end
  end
end

它失败了:

1) StatsController GET 'users_in_system' for non-signed users should deny access
     Failure/Error: get :users_in_system
     ActionController::RoutingError:
       No route matches {:controller=>"stats", :action=>"users_in_system"}
     # ./spec/controllers/stats_controller_spec.rb:11:in `block (4 levels) in <top (required)>'

在浏览器中,此页面打开,一切正常。 rspec怎么会产生这样的错误?!

UPD1:我想,路由中的 i18n 集成可能会破坏我的测试。

UPD2:

我的application.rb

require File.expand_path('../boot', __FILE__)
require 'rails/all'

if defined?(Bundler)
  # If you precompile assets before deploying to production, use this line
  Bundler.require(*Rails.groups(:assets => %w(development test)))
  # If you want your assets lazily compiled in production, use this line
  # Bundler.require(:default, :assets, Rails.env)
end

module MyApp
  class Application < Rails::Application
    config.i18n.default_locale = :ru
    config.encoding = "utf-8"
    config.filter_parameters += [:password]
    config.active_support.escape_html_entities_in_json = true
    config.active_record.whitelist_attributes = true
    config.assets.enabled = true
    config.assets.version = '1.0'
  end
end

【问题讨论】:

  • 不需要登录什么的?
  • @apneadiving 否。用户不应登录以查看此页面。
  • 我认为@shioyama 检查I18n.default_locale 是正确的,我还要补充一点,如果您打算检查您的规范中的每个语言环境(我愿意),然后检查this StackOverflow question关于 i18nizing RSpec 测试的一些想法。我的首选方式是this answer 处理同一个问题。

标签: ruby-on-rails ruby ruby-on-rails-3 rspec


【解决方案1】:

我怀疑问题是I18n.default_locale 没有在 rspec 中正确设置,这会破坏您的路由。

我建议的第一件事是查看I18n.default_locale 是否真的在您的测试中设置。

几个问题开始:

  • 如果将get :users_in_system 更改为get :users_in_system, :locale =&gt; :en,测试是否通过?
  • 尝试将 routes.rb 中的 I18n.default_locale 替换为其显式值,例如 :en,看看是否有任何改变。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多