无法登录RSpec功能测试

时间:2012-03-04 10:56:46

标签: ruby-on-rails ruby-on-rails-3 rspec capybara

当我在测试中直接调用put / delete / post等时,我无法通过RSpec测试。我认为这是因为会话没有通过直接调用put / delete等请求传递,但我不是百分百肯定。

更多信息:这是来自rails指南,我在第8章(http://ruby.railstutorial.org/chapters/sign-in-sign-out?version=3.2#sec:sign_in_out_exercises

中实施了使用session而不是cookie的练习

此测试通过(所以我非常确定会话在浏览器中正常运行):

describe "signin" do
  before { visit signin_path }

  describe "with valid information" do
    let(:user) { FactoryGirl.create(:user) }
    before do
      fill_in "Email",    with: user.email
      fill_in "Password", with: user.password
      click_button "Sign in"
    end

    it { should have_selector('title', text: user.name) }
    it { should have_link('Users',    href: users_path) }
    it { should have_link('Profile', href: user_path(user)) }
    it { should have_link('Settings', href: edit_user_path(user)) }
    it { should have_link('Sign out', href: signout_path) }
    it { should_not have_link('Sign in', href: signin_path) }
    describe "followed by signout" do
      before { click_link "Sign out" }
      it { should have_link('Sign in') }
    end
  end
end

这个没有(之前的行失败):

describe "Authentication" do
    describe "authorization" do
        describe "as non-admin user" do
            let(:user) { FactoryGirl.create(:user) }
            let(:non_admin) { FactoryGirl.create(:user) }
            before { sign_in non_admin }
            describe "submitting a DELETE request to the Users#destroy action" do
                before { delete user_path(user) }
                specify { response.should redirect_to(root_path) }
            end
        end
    end
end

错误是:

Authentication authorization as non-admin user submitting a DELETE request to the Users#destroy action 
Failure/Error: before { delete user_path(user) }
NoMethodError:
  undefined method `admin?' for nil:NilClass
   - ./app/controllers/users_controller.rb:55:in `admin_user'
   - ./spec/requests/authentication_pages_spec.rb:133:in `block (5 levels) in <top (required)>'

用户控制器和会话助手的相关位:

class UsersController < ApplicationController
before_filter :admin_user,     only: :destroy

def destroy
  User.find(params[:id]).destroy
  flash[:success] = "User destroyed."
  redirect_to users_path
end

private

  def admin_user
    redirect_to(root_path) unless current_user.admin?
  end

end

module SessionsHelper
  def sign_in(user)
    #cookies.permanent[:remember_token] = user.remember_token
    session[:user_id] = user.id
    self.current_user= user
  end
  def sign_out
    #cookies.delete(:remember_token)
    session[:user_id] = nil
    self.current_user= nil
  end

  def signed_in?
    !current_user.nil?
    #!session[:user_id].nil?
  end

  def current_user=(user)
    @current_user = user
  end

  def current_user
    @current_user ||= User.find(session[:user_id]) if session[:user_id]
  end
  def current_user?(user)
    user == current_user
  end

  def redirect_back_or(default)
    redirect_to(session[:return_to] || default)
    clear_return_to
  end

  def store_location
    session[:return_to] = request.fullpath
  end
  def clear_return_to
    session.delete(:return_to)
  end

end

1 个答案:

答案 0 :(得分:0)

您确定可以为这样的请求规范设置会话变量吗?我定义了一个导航到登录的函数,填充表单并单击登录按钮。我之前在需要登录用户的规格之前调用它。不过,我对于要求规格相对较新,所以可能还有其他方法可以做到这一点。