Как проверить, что before_filter работает правильно с RSpec в Rails - PullRequest
13 голосов
/ 04 мая 2011

У меня есть 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 NOT беспокоиться о существовании шаблона.

Ответы [ 3 ]

8 голосов
/ 04 мая 2011

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

* 1003 Е.Г. *

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 .

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

0 голосов
/ 03 мая 2016

Окончательное решение, благодаря 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

0 голосов
/ 05 августа 2014

Для расширения ответа @ nathanvda :

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...