1

Я вижу очень странное поведение, когда работает ли фильтр, зависит от того, было ли оно запущено в первом spec для использования этого контроллера.Фильтры контроллеров Rails, после которых они были удалены, восстанавливаются

Так я свел вниз до минимального контроллера:

class WtfController < ActionController::Base 
    before_filter :raise_error 

    def index 
    render nothing: true, status: 200 
    end 

    private 
    def raise_error 
    raise OMGError 
    end 
end 

(OMGError только подклассы StandardError)

И тестового примера:

describe 'wtfspec' do 
    it 'with filter' do 
    expect do 
     controller = set_up_controller 
     controller.process(:index) 
    end.to raise_error 
    end 

    it 'without filter' do 
    expect do 
     controller = set_up_controller 
     controller.class.skip_filter :raise_error 
     controller.process(:index) 
    end.not_to raise_error 
    end 
end 

def set_up_controller 
    controller = WtfController.new 
    controller.request = ActionController::TestRequest.new 
    controller.response = ActionController::TestResponse.new 
    controller 
end 

Фильтр должен быть пропущен во втором тесте, но это не так.

Если первый блок ожидания не запущен, то проходит второй тест. Это только если он запущен, второй не удается. Аналогично, если I skip_filter в первом тесте и использовать before_filter, чтобы прочитать его для второго теста, второй не сможет запустить фильтр, хотя он должен.

Вот вещь - если я исследую список фильтров, установленных на WtfController (с использованием controller.class._process_action_callbacks.map(&:filters)) в спецификации (во втором тесте) прямо перед controller.process линии, то она действительно была успешно удалена, skip_filter линия работает отлично , Но если я исследую его внутри контроллера (в raise_error), он, похоже, как-то читается!

Замечание 'readded', а не 'reappeared': Object_id обратного вызова raise_error, который фактически выполняется, отличается от исходного (тот, который был там до запуска skip_filter). Но object_id массива фильтров (фактически ActiveSupport::Callbacks::CallbackChain) остается таким же, как и контроллер.

(Edit: оказывается, все объекты обратного вызова имеют разные object_ids, а не только снятые один Тайна углубляется ....)

поведение такого же, является ли каждый из двух испытаний новая-х вверх новый объект контроллера или повторное использование одного (как и следовало ожидать, поскольку фильтры являются свойством объекта класса WtfController, а не экземпляров).

Я провел день, отлаживая это и совершенно озадачен. Любое понимание было оценено. Версия Rails - 3.2.21. Спасибо :)

+0

Hahaha .. Nice контроллер name * WtfController *. –

ответ

0

После тестирования различных версий рельсов этого поведения в 4.0 не происходит. Вероятно, это была ошибка в рельсах, которые теперь исправлены. Возможно, связано с this commit в activesupport.

Смежные вопросы