1

我有这样的控制器

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

我想为控制器编写测试。所以我尝试了这个规范

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
4

1 回答 1

3

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

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

几个问题开始:

  • 如果更改get :users_in_systemget :users_in_system, :locale => :en测试是否通过?
  • 尝试用I18n.default_locale它的显式值替换 routes.rb ,比如:en,看看是否有任何改变。
于 2012-08-31T21:53:07.900 回答