5

В моем приложении Rails 3.2 я пытаюсь использовать config.exceptions_app для маршрутизации исключений через таблицу маршрутизации для отображения страниц с ошибками (особенно для запрещенных для 401). Вот что у меня до сих пор для конфигурации:Как сделать config.exceptions_app работать с rspec

# application.rb 
config.action_dispatch.rescue_responses.merge!('Error::Forbidden' => :forbidden) 
config.exceptions_app = ->(env) { ErrorsController.action(:show).call(env) } 

# development.rb 
config.consider_all_requests_local  = false 

# test.rb 
config.consider_all_requests_local  = false 

А теперь мясо вопроса:

module Error 
    class Forbidden < StandardError 
    end 
end 

class ErrorsController < ApplicationController 
    layout 'error' 

    def show 
    exception  = env['action_dispatch.exception'] 
    status_code  = ActionDispatch::ExceptionWrapper.new(env, exception).status_code 
    rescue_response = ActionDispatch::ExceptionWrapper.rescue_responses[exception.class.name] 

    render :action => rescue_response, :status => status_code, :formats => [:html] 
    end 

    def forbidden 
    render :status => :forbidden, :formats => [:html] 
    end 
end 

Когда я хочу сделать что 401 ответ, я просто raise Error::Forbidden, который, в развитии окружающая среда работает отлично. Но при работе пример в RSpec, например .:

it 'should return http forbidden' do 
    put :update, :id => 12342343343 
    response.should be_forbidden 
end 

он с треском проваливается:

1) UsersController PUT update when attempting to edit another record should return http forbidden 
    Failure/Error: put :update, :id => 12342343343 
    Error::Forbidden: 
    Error::Forbidden 

Может кто-то помочь мне понять, почему это не работает в моей тестовой среде? I может поставить #rescue_from в ApplicationController, но если мне нужно сделать это, чтобы заставить мои тесты работать, я не уверен, что точка использования config.exceptions_app в первую очередь. : - \

EDIT: В качестве обходного пути я закончил установку следующего в конце config/environment/test.rb. Это хецка грубая, но, похоже, все в порядке.

module Error 
    def self.included(base) 
    _not_found = -> do 
     render :status => :not_found, :text => 'not found' 
    end 

    _forbidden = -> do 
     render :status => :forbidden, :text => 'forbidden' 
    end 

    base.class_eval do 
     rescue_from 'ActiveRecord::RecordNotFound', :with => _not_found 
     rescue_from 'ActionController::UnknownController', :with => _not_found 
     rescue_from 'AbstractController::ActionNotFound', :with => _not_found 
     rescue_from 'ActionController::RoutingError', :with => _not_found 
     rescue_from 'Error::Forbidden', :with => _forbidden 
    end 
    end 
end 

ответ

2

В config/environments/test.rb комплекте:

config.action_dispatch.show_exceptions = true 
+0

Спасибо за ответ, но у меня уже есть эта строка в этом файле, и это не решает мою проблему. Если я прокомментирую модуль Error, который я покажу выше, мои тесты вернутся к ошибке. – 7over21

0

Я была такая же проблема. Будьте осторожны, когда вы делаете свое исключение. Если оно находится в before_filter/before_action, ваше исключение будет проглочено. Переместите ваш поисковый код в фактический метод, и ваше исключение должно появиться в ваших спецификациях.