Ruby on rails 在Rails 3中与Rspec和;水豚

Ruby on rails 在Rails 3中与Rspec和;水豚,ruby-on-rails,session,rspec,capybara,Ruby On Rails,Session,Rspec,Capybara,我正试图编写与rspec、factory_girl和capybara的集成测试。我也安装了cucumber,但据我所知,我没有使用它 我基本上想用我的用户预填充数据库,然后转到我的主页并尝试登录。它应该重定向到用户路径(@user) 但是,会话似乎没有持久化到my/rspec/requests/integration测试中 我的规格:/rspec/requests/users\u spec.rb require 'spec_helper' describe "User flow" do

我正试图编写与rspec、factory_girl和capybara的集成测试。我也安装了cucumber,但据我所知,我没有使用它

我基本上想用我的用户预填充数据库,然后转到我的主页并尝试登录。它应该重定向到用户路径(@user)

但是,会话似乎没有持久化到my/rspec/requests/integration测试中

我的规格:/rspec/requests/users\u spec.rb

require 'spec_helper'

describe "User flow" do

  before(:each) do
    @user = Factory(:user)
  end

  it "should login user" do

    visit("/index")

    fill_in :email, :with => @user.email
    fill_in :password, :with => @user.password
    click_button "Login"
    assert current_path == user_path(@user)
  end
end
返回:

Failures:

  1) User flow should login user
     Failure/Error: assert current_path == user_path(@user)
     <false> is not true.
     # (eval):2:in `send'
     # (eval):2:in `assert'
     # ./spec/requests/users_spec.rb:16
故障:
1) 用户流应该登录用户
失败/错误:断言当前路径==用户路径(@user)
事实并非如此。
#(eval):2:在'send'中
#(eval):2:在“断言”中
#./spec/requests/users\u spec.rb:16
相反,它会重定向到我的please\u login\u路径-如果由于任何原因登录失败(或者未设置会话[:user\u id]),则会发生这种情况

如果我尝试放置session.inspect,它将作为nil对象失败


如果我在控制器测试(/rspec/controllers/sessions\u spec.rb)中尝试这样做,我可以毫无问题地访问会话,并且我可以调用会话[:user\u id]

如果您使用的是designe,那么您将需要包括Warden::Test::Helpers(在spec\u helper的要求之后是一个好地方),如所述


对会话的调用返回nil,因为当作为集成测试运行时,capybara不提供对它的访问。

您可能已经离开了这个问题,但我只是在为同样的问题挣扎。原来这是个语法问题。我用符号来表示
:email
:password
,我应该用字符串来代替(
“email”
“password”

换句话说,请尝试更改以下内容:

fill_in :email, :with => @user.email
fill_in :password, :with => @user.password
为此:

fill_in "email", :with => @user.email
fill_in "password", :with => @user.password

我也有同样的问题,尽管填写表单可能是一些人的选择,但我不得不推出自己的身份验证ruby,因为我使用的是第三方身份验证系统(确切地说是Janrain)。。。。在我的测试中,我最终使用了如下内容:

以下是我在spec/support/test\u helpers\u和\u stuff.rb中的内容

module AuthTestHelper

  class SessionBackdoorController < ::ApplicationController
    def create
      sign_in User.find(params[:user_id])
      head :ok
    end
  end

  begin
    _routes = Rails.application.routes
    _routes.disable_clear_and_finalize = true
    _routes.clear!
    Rails.application.routes_reloader.paths.each{ |path| load(path) }
    _routes.draw do
      # here you can add any route you want
      match "/test_login_backdoor", to: "session_backdoor#create"
    end
    ActiveSupport.on_load(:action_controller) { _routes.finalize! }
  ensure
    _routes.disable_clear_and_finalize = false
  end

  def request_signin_as(user)
    visit "/test_login_backdoor?user_id=#{user.id}"
  end

  def signin_as(user)
    session[:session_user] = user.id
  end

end
顺便说一句,我在尝试了提出的解决方案后提出了解决方案,但它们都不适用于我。(但它们确实启发了我的解决方案)


祝你好运

我不知道这是否相关,但您不应该通过键入@user.password来获取用户密码。这是你的应用程序中的一个安全漏洞。您是否使用纯文本存储密码?这与此无关,也可能不是安全漏洞。对#password的调用只返回密码,因为它是由工厂在实例变量中设置的。很可能他正在使用Desive或类似的东西,这些东西不会以明文形式将密码属性持久化到db中,因此如果该实例变量消失,它将不可用。
describe "Giveaway Promotion" do
  context "Story: A fan participates in a giveaway", js: :selenium do
    context "as a signed in user" do

      before :each do
        @user = Factory(:user)
        request_signin_as @user
      end

      it "should be able to participate as an already signed in user" do
        visit giveaway_path
        ....
      end
    end
  end
end