Rails,Devise,Rspec:未定义的方法' sign_in'

时间:2014-05-25 20:27:47

标签: ruby-on-rails-4 rspec devise

我正在尝试在Rails中编写Rspec测试,使用Devise帮助方法进行登录和注销。 sign_in方法无效。但是,在对应用程序进行一系列更改之前,它已经提前工作了。

我尝试过的事情:

  • 我在Rspec.configure中包含了测试助手。
  • 使用Warden的login_as
  • 清除Rails缓存。
  • 摆脱Capybara以查看是否导致问题
  • 我没有在我的控制器规范中明确设置会话(例如,没有valid_session)
到目前为止,没有骰子。对于使用已登录用户测试控制器,我需要做些什么?

错误讯息:

 OrderItemsController GET #index renders the :index view
 Failure/Error: sign_in :admin
 NoMethodError:
      undefined method `sign_in' for #  <RSpec::ExampleGroups::OrderItemsController_2::GETIndex:0x00000102c002d0>
 # ./spec/controllers/order_items_controller_spec.rb:6:in `block (2 levels) in <top (required)>'

控制器规格

require 'spec_helper'

describe OrderItemsController do
    before (:each) do
        admin = create(:admin)
        sign_in :admin
    end

    describe "GET #index" do
        it "renders the :index view" do
            get :index
            expect( response ).to render_template :index
        end
    end
end

spec_helper.rb

require 'rspec/rails'
require 'capybara/rspec'

RSpec.configure do |config|

  config.include ApplicationHelper
  config.include ControllersHelper
  config.include UsersHelper
  config.include Devise::TestHelpers, type: :controller
  config.include FactoryGirl::Syntax::Methods

end

的Gemfile

group :development, :test do
    gem 'rspec-rails', '~> 3.0.0.beta'
    gem 'capybara'
    gem 'factory_girl_rails'
    gem 'faker'
    gem 'dotenv-rails'
    gem 'guard'
    gem 'guard-annotate'
    gem 'guard-rspec', require: false
    gem 'guard-livereload', require: false
    gem 'foreman'
end

工厂/ user.rb

FactoryGirl.define do

    factory :user do
        first                   { Faker::Name.first_name }
        last                    { Faker::Name.last_name }
        email                   { Faker::Internet.email }
        admin                   false
        password                "secrets1"
        password_confirmation   "secrets1"
        confirmed_at            Date.today

        factory :admin do
            admin               true
        end
    end
end

提前致谢。

7 个答案:

答案 0 :(得分:29)

您最近是否像我一样升级到RSpec 3?这来自the RSpec 3 documentation

  

自动添加元数据   3.0.0之前的RSpec版本会自动将元数据添加到基于的规范   他们在文件系统上的位置。这对新用户来说既困惑又不困惑   对于一些资深用户来说是理想的。

     

在RSpec 3中,必须明确启用此行为:

​# spec/rails_helper.rb
RSpec.configure do |config|
    config.infer_spec_type_from_file_location!
end
     

由于这种假设行为在教程中如此普遍,因此默认   rails生成的配置生成rspec:install启用此功能。

     

如果您按照上面列出的规范目录结构而拥有   配置infer_spec_type_from_file_location !, RSpec会自动进行   包括每种类型的正确支持功能。

添加该配置代码后,我不再需要指定规范类型(例如type: :controller)。

答案 1 :(得分:8)

我找到了解决方案。我明确地将控制器的Describe块定义为控制器类型。

describe OrderItemsController, :type => :controller do

我仍然不明白为什么这段代码能够提前运行,但现在需要这个(看似多余的)显式声明。无论如何,我很高兴学习这里发生的事情。谢谢!

答案 2 :(得分:6)

我可以为你提供一个例子(适用于我 - rspec / capybara / simplecov等。)

<强>规格/ spec_helper.rb

 require 'capybara/rspec'
 require 'capybara/rails'

 RSpec.configure do |config|
  config.use_transactional_fixtures = true

  config.infer_base_class_for_anonymous_controllers = false

  config.include FactoryGirl::Syntax::Methods
  config.include Devise::TestHelpers, type: :controller
  config.include Capybara::DSL
  config.include Warden::Test::Helpers
  config.include Rails.application.routes.url_helpers
end

<强>规格/集成/ user_flow_spec.rb

require 'spec_helper'

feature 'Verify contract' do
  # Create employee
  let(:employee) { create(:employee) }
  let (:book) { create(:book) }

  # Sign in employee before each test!
  before :each do
    login_as employee, scope: :user
  end

  scenario 'create book' do
    # Visit Index and click to create
    visit employee_books_path
    click_link 'Create'
    expect(current_path).to eq(employee_books_path)
  end
end

我希望它会好的:)我认为你的问题是缺少Warden测试助手......

答案 3 :(得分:4)

您可以在文件spec / spec_helper.rb中使用Devise助手:

RSpec.configure do |config|
   config.include Devise::TestHelpers, type: :controller
end

答案 4 :(得分:1)

如果您需要在 请求规范 文件中使用 sign_in 方法,那么您应该包含以下内容:

config.include Devise::Test::IntegrationHelpers, type: :request

答案 5 :(得分:0)

对于Rails 5和Rspec 3,您需要将其添加到spec_helper.rb

  

config.include Devise :: Test :: ControllerHelpers,输入:: controller

答案 6 :(得分:-1)

您可以像这样使用 login_as 方法:

# rails_helper.rb
RSpec.configure do |config|
   config.include Warden::Test::Helpers
end

在您的规范文件中使用:

#spec/integration/user_flow_spec.rb
before :each do
    employee = create(:employee)
    login_as employee, scope: :user
end