Rails, Restful Authentication и RSpec — Как тестировать новые модели, требующие аутентификации

StackOverflow https://stackoverflow.com/questions/64827

Вопрос

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

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

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

Это было полезно?

Решение

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

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

Другие советы

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

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

Приведенный выше пример работает, когда для моего before_filter установлен метод аутентификации:

before_filter :authenticate

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

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

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

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

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

РСпец:Он должен вести себя как

rspec, restful_authentication и login_required

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

Высыхание RSpec вашего CRUD-контроллера

Чтобы высмеять пользователя, входящего в систему, я взломал контроллер, чтобы установить @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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top