Подтвердить что ты не робот

Как проверить, что before_filter работает правильно с RSpec в Rails

У меня есть check_user_access_control before_filter в моем ApplicationController, который проверяет зарегистрированные роли пользователя и разрешения, прежде чем он его пропустит. Я пытаюсь написать несколько тестов, и я не могу найти хороший способ сделать это.

Для простых действий индекса я просто делаю:

it "allows access to mod" do
  login_as(Factory(:mod)) # this is a spec helper
  get :index
  response.code.should == "200"
end

и все работает отлично. Для редактирования/показа/создания и других действий, которым требуются некоторые параметры, взаимодействия с базой данных и возможной перенаправленности после их запуска, требуется слишком много других материалов, которые нужно зачистить.

Есть ли способ проверить, было ли вызвано определенное действие после before_filters? Я ищу что-то вроде controller.should_receive(:action_name) (которое не работает) для замены строки response.code.should == "200" с.

: rails 3.0.4 и rspec 2.5

Я попробовал другой подход. У нас есть метод в ApplicationController под названием redirect_to_login, который я сейчас проверяю с помощью controller.should_receive(:redirect_to_login) и работает.

Пока он правильно распознает, разрешен ли пользователь или нет, он заглушает метод, что означает, что действие контроллера выполняется независимо от того, разрешен ли пользователь. Кроме того, действие зависит от параметров и базы данных, и мы этого не хотим.

Если теперь я закрою метод действия с помощью controller.stub!(:action_name), действие не выполняется, но RSpec все еще ищет шаблон. Ну, в некоторых действиях нет шаблонов, они просто заканчиваются на redirect_to :action => :somewhere_else или render :text => "foobar", которые в этот момент нас не волнуют.

В роде мне сейчас нужно найти способ заставить RSpec НЕ беспокоиться о существовании шаблона.

4b9b3361

Ответ 1

При выполнении stubbing вы все равно можете дать фиктивную реализацию. Внутри этой реализации вы могли бы затем вызвать ошибку, чтобы убедиться, что все выполнение остановлено, или вы все равно перенаправляете.

например.

controller.should_receive(:redirect_to_log) { redirect_to login_url }

или

controller.should_receive(:redirect_to_log) { raise StandardError.new('login error') }
expect { get :index }.to raise_error

Для получения дополнительной информации ознакомьтесь с замечательной документацией rspec.

Надеюсь, что это поможет.

Ответ 2

Чтобы продлить ответ @nathanvda:

При выполнении stubbing вы все равно можете дать фиктивную реализацию. Внутри этой реализации [...] все равно перенаправляется.

Вам нужно указать controller в блоке:

expect(controller).to receive(:redirect_to_log) { controller.redirect_to login_url }

RSpec имеет совпадение, которое также называется redirect_to, которое имеет преимущество при поиске метода. Вызов его непосредственно на контроллере работает вокруг этого.

Ответ 3

Окончательное решение, благодаря nathanvda:

it "allows access to moderator" do
  login_as(Factory(:mod))
  controller.stub!(action) { raise "HELL" }

  controller.should_not_receive(:redirect_to_login)
  expect { get action }.to raise_error(/HELL/)
end

it "denies access to user" do
  login_as(Factory(:user))

  controller.should_receive(:redirect_to_login) { raise "HELL" }
  expect { get :index }.to raise_error(/HELL/)
end

размещен на https://gist.github.com/957565