Rails, Restful Authentication & RSpec - Как протестировать новые модели, требующие аутентификации - PullRequest
17 голосов
/ 15 сентября 2008

Я создал обучающее приложение, используя Борт , которое является базовым приложением, включающим Restful Authentication и RSpec. Я запустил его и запустил и добавил новый объект, который требует, чтобы пользователи вошли в систему, прежде чем они смогут что-либо делать (before_filter :login_required в контроллере). [править: я должен также упомянуть, что пользователь has_many нового класса и только пользователь должен видеть его.]

Я создал новую модель / контроллер с использованием генераторов Rspec, которые создали ряд тестов по умолчанию. Все они проходят, если before_filter нет, но несколько неудач, как и следовало ожидать, как только before_filter на месте.

Как заставить сгенерированные тесты запускаться так, как будто есть / нет зарегистрированный пользователь? Нужна ли целая партия соответствия, не вошедшая в систему - тесты перенаправления? Я предполагаю, что это какая-то техника насмешки или фиксации, но я новичок в RSpec и немного в стороне. Хорошие учебные ссылки по RSpec также приветствуются.

Ответы [ 4 ]

7 голосов
/ 22 декабря 2009

Когда проверяется не аутентификация, а тестирование контроллеров, которым требуется аутентификация пользователя, я обычно заглушаю метод фильтра:

before(:each) do
  controller.stub!(:authenticate).and_return(true)
end

Приведенный выше пример работает, когда для моего before_filter задан метод authenticate:

before_filter :authenticate

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

private
def authenticate
  authenticate_or_request_with_http_basic do |user,password|
    user == USER_NAME && password == PASSWORD
  end
end

Я думаю, что это довольно простой способ тестирования.

7 голосов
/ 15 сентября 2008

У меня очень похожая настройка, и ниже приведен код, который я сейчас использую для тестирования этого материала. В каждом из describe s я вставил:

it_should_behave_like "login-required object"
def attempt_access; do_post; end

Если все, что вам нужно, это логин или

it_should_behave_like "ownership-required object"
def login_as_object_owner; login_as @product.user; end
def attempt_access; do_put; end
def successful_ownership_access
  response.should redirect_to(product_url(@product))
end

Если вам нужно владение. Очевидно, что вспомогательные методы меняются (очень мало) с каждым ходом, но это делает большую часть работы за вас. Это у меня в spec_helper.rb

shared_examples_for "login-required object" do
  it "should not be able to access this without logging in" do
    attempt_access

    response.should_not be_success
    respond_to do |format|
      format.html { redirect_to(login_url) }
      format.xml { response.status_code.should == 401 }
    end
  end
end

shared_examples_for "ownership-required object" do
  it_should_behave_like "login-required object"

  it "should not be able to access this without owning it" do
    attempt_access

    response.should_not be_success
    respond_to do |format|
      format.html { response.should be_redirect }
      format.xml { response.status_code.should == 401 }
    end
  end

  it "should be able to access this if you own it" do
    login_as_object_owner
    attempt_access

    if respond_to?(:successful_ownership_access)
      successful_ownership_access
    else
      response.should be_success
    end
  end
end
4 голосов
/ 16 сентября 2008

Я нашел несколько ответов на свой вопрос. По сути, мне нужно было понять, как отключить пользователя от restful_authentication, чтобы автоматически сгенерированные тесты контроллера rspec могли пройти, хотя я добавил before_filter: login_required.

Вот несколько из моих только что найденных ресурсов:

RSpec: он должен вести себя как

rspec, restful_authentication и login_required

с использованием restful_authentication current_user внутри спецификаций контроллера

СУШКА CRUD-контроллера RSpecs

1 голос
/ 27 сентября 2008

Чтобы издеваться над пользователем, вошедшим в систему, я взломал контроллер, чтобы установить @current_user вручную:

module AuthHelper
  protected

  def login_as(model, id_or_attributes = {})
    attributes = id_or_attributes.is_a?(Fixnum) ? {:id => id} : id_or_attributes
    @current_user = stub_model(model, attributes)
    target = controller rescue template
    target.instance_variable_set '@current_user', @current_user

    if block_given?
      yield
      target.instance_variable_set '@current_user', nil
    end
    return @current_user
  end

  def login_as_user(id_or_attributes = {}, &block)
    login_as(User, id_or_attributes, &block)
  end
end
...