#ruby-on-rails #rspec
#ruby-on-rails #rspec
Вопрос:
Вопрос:
Как настроить / смоделировать тест маршрутизации rspec, чтобы он больше походил на среду производственной стойки?
Бонусные баллы за возможность сначала вызвать функцию аутентификации контроллера (например, ApplicationController.authenticate_user для установки сеанса [:current_user_id]
Подробные сведения:
Я использую route: ограничения, чтобы иметь www.example.com / маршрут к двум разным контроллерам и представлениям в зависимости от того, авторизован пользователь или нет.
root :to => 'intentions#latest', :constraints => lambda {|r| r.env['rack.session'].has_key?(:current_user_id) }
root :to => 'welcome#index'
Я хотел убедиться, что этот фрагмент хрупкой маршрутизации прошел надлежащий тест. Cukes тестируют это, но я хотел провести немного более глубокое тестирование, особенно потому, что я перепутал:current_user_id и cukes этого не уловили. Например, я указал жирным пальцем:current_user_id в методе authenticate_user () моего ApplicationController. Хотелось бы вызвать это в before (:each) и убедиться, что я устанавливаю правильный ключ сеанса.
Итак, я создал файл с именем /spec/routing/auth_routing_spec.rb и попытался следовать руководству наhttp://relishapp.com/rspec/rspec-rails/v/2-6-rc/dir/routing-specs . Я создал следующую спецификацию:
it "/ should send me to home page" do
get('/').should route_to(:controller => :index)
end
Когда я запускаю спецификацию, я сталкиваюсь с этой ошибкой на маршруте, который имеет ограничение:. Я предполагаю, что env [‘rack.session’] не существует. Я попытался смоделировать объект запроса через Rails.application.call(Rack::MockRequest.env_for('/'))
, но это не помогло.
Failure/Error: get('/').should route_to(:controller => :index)
NoMethodError:
undefined method `has_key?' for nil:NilClass
Скучные детали приложения
rake about
дает
Ruby version 1.9.2 (x86_64-darwin10.6.0)
RubyGems version 1.6.2
Rack version 1.2
Rails version 3.0.7
Active Record version 3.0.7
Action Pack version 3.0.7
Active Resource version 3.0.7
Action Mailer version 3.0.7
Active Support version 3.0.7
grep rspec gemfile.info
дает
remote: git://github.com/rspec/rspec-rails.git
rspec-rails (2.6.0.rc6)
rspec (= 2.6.0.rc6)
rspec (2.6.0.rc6)
rspec-core (= 2.6.0.rc6)
rspec-expectations (= 2.6.0.rc6)
rspec-mocks (= 2.6.0.rc6)
rspec-core (2.6.0.rc6)
rspec-expectations (2.6.0.rc6)
rspec-mocks (2.6.0.rc6)
rspec-rails!
Комментарии:
1. Вы пробовали создать метод env где-нибудь в цепочке методов? Итак, например, найдите класс для привязки, который может быть родительским классом класса маршрутизации, а затем присоедините к этому классу. Это может быть проще, чем пытаться вставить rack в тестовый набор, который его не использует. Например, AppName::Application.stub(:env).and_return(double(:x => y)) и т.д.
Ответ №1:
Я делаю что-то вроде в моих спецификациях контроллера, может быть, здесь сработал бы тот же подход?
describe "some controller" do
it "does something" do
request.stub(:env => {'rack.session' => {'current_user' => '42'})
get :my_action
response.should be_cool
end
end
По размышлении, лучшим подходом для вас, вероятно, является:
class CurrentUserConstraint
def self.matches?(request)
request.session[:current_user_id].present?
end
end
и:
root :to => 'intentions#latest', :constraints => CurrentUserConstraint.new
и тогда у вас есть ваша логика в классе, который легко тестируется.
Комментарии:
1. Я думаю, что комбинация этих двух великолепна. Тестирование ограничения как собственного объекта — это здорово. Бонус за возможность также протестировать маршруты путем прерывания сеанса. Попробую в эти выходные.