使用devise进行rspec集成测试时抛出NoMethodError错误

7

我在这里发布了一个类似的错误,但所有方法都不能解决我的问题。

我的文件'spec/request/news_controller_spec.rb'看起来像:

require 'spec_helper'

describe "NewsController" do

  include Devise::TestHelpers

  describe "GET /news" do

    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:user]
      @user = Factory.create(:user)
      @user.confirm!
      sign_in @user
    end

    it "after login should show the latest news an screen" do
      page.should have_content("News")
    end
  end
end

如果我运行测试,我会得到:

Failures:

  1) Campaigns GET /news works!
     Failure/Error: Unable to find matching line from backtrace
     NoMethodError:
       undefined method `env' for nil:NilClass
     # /Users/.../gems/devise-1.5.3/lib/devise/test_helpers.rb:25:in `setup_controller_for_warden'
     # /Users/.../gems/rspec-rails-2.8.1/lib/rspec/rails/adapters.rb:15:in `block (2 levels) in setup'
     # /Users/.../gems/rspec-core-2.8.0/lib/rspec/core/hooks.rb:35:in `instance_eval'
     # /Users/.../gems/rspec-core-2.8.0/lib/rspec/core/hooks.rb:35:in `run_in'
     # /Users/.../gems/rspec-core-2.8.0/lib/rspec/core/hooks.rb:70:in `block in run_all'
     # /Users/.../gems/rspec-core-2.8.0/lib/rspec/core/hooks.rb:70:in `each'
     # /Users/.../gems/rspec-core-2.8.0/lib/rspec/core/hooks.rb:70:in `run_all'
     # /Users/.../gems/rspec-core-2.8.0/lib/rspec/core/hooks.rb:368:in `run_hook'
     # /Users/.../gems/rspec-core-2.8.0/lib/rspec/core/example_group.rb:292:in `block in run_before_each_hooks'
     # /Users/.../gems/rspec-core-2.8.0/lib/rspec/core/example_group.rb:292:in `each'
     # /Users/.../gems/rspec-core-2.8.0/lib/rspec/core/example_group.rb:292:in `run_before_each_hooks'
     # /Users/.../gems/rspec-core-2.8.0/lib/rspec/core/example.rb:217:in `run_before_each'
     # /Users/.../gems/rspec-core-2.8.0/lib/rspec/core/example.rb:79:in `block in run'
     # /Users/.../gems/rspec-core-2.8.0/lib/rspec/core/example.rb:173:in `with_around_hooks'
     # /Users/.../gems/rspec-core-2.8.0/lib/rspec/core/example.rb:77:in `run'
     # /Users/.../gems/rspec-core-2.8.0/lib/rspec/core/example_group.rb:355:in `block in run_examples'
     # /Users/.../gems/rspec-core-2.8.0/lib/rspec/core/example_group.rb:351:in `map'
     # /Users/.../gems/rspec-core-2.8.0/lib/rspec/core/example_group.rb:351:in `run_examples'
     # /Users/.../gems/rspec-core-2.8.0/lib/rspec/core/example_group.rb:337:in `run'
     # /Users/.../gems/rspec-core-2.8.0/lib/rspec/core/example_group.rb:338:in `block in run'
     # /Users/.../gems/rspec-core-2.8.0/lib/rspec/core/example_group.rb:338:in `map'
     # /Users/.../gems/rspec-core-2.8.0/lib/rspec/core/example_group.rb:338:in `run'
     # /Users/.../gems/rspec-core-2.8.0/lib/rspec/core/command_line.rb:28:in `block (2 levels) in run'
     # /Users/.../gems/rspec-core-2.8.0/lib/rspec/core/command_line.rb:28:in `map'
     # /Users/.../gems/rspec-core-2.8.0/lib/rspec/core/command_line.rb:28:in `block in run'
     # /Users/.../gems/rspec-core-2.8.0/lib/rspec/core/reporter.rb:34:in `report'
     # /Users/.../gems/rspec-core-2.8.0/lib/rspec/core/command_line.rb:25:in `run'
     # /Users/.../gems/rspec-core-2.8.0/lib/rspec/core/runner.rb:80:in `run_in_process'
     # /Users/.../gems/rspec-core-2.8.0/lib/rspec/core/runner.rb:69:in `run'
     # /Users/.../gems/rspec-core-2.8.0/lib/rspec/core/runner.rb:10:in `block in autorun'

我按照https://github.com/plataformatec/devise/wiki/How-To%3a-Controllers-and-Views-tests-with-Rails-3-%28and-rspec%29 和其他类似的问题指南操作,但是我找不到解决方案。我使用以下gem集:
  • capybara (1.1.2)
  • devise (1.5.3)
  • factory_girl_rails (1.6.0)
  • rails (3.2.0, 3.1.1)
  • rspec (2.8.0)
  • rspec-core (2.8.0)
  • rspec-expectations (2.8.0)
  • rspec-mocks (2.8.0)
  • rspec-rails (2.8.1)
和一些其他的gems。请问有人能帮我让我的集成测试与已登录的用户运行起来吗?在这种情况下,只有在用户登录后才会显示新闻。谢谢。

你确定你没有混淆Test::UnitRSpec的配置吗?从rspec-rails-2.0.0和devise-1.1开始,将devise放入你的规范中的最佳方法是将以下内容添加到spec_helper中: https://gist.github.com/1682113 - jibiel
希望如此。我有一个文件_spec/support/devise.rb_,在这个文件中,我写了RSpec.configure do |config| config.include Devise::TestHelpers, :type => :controller end。支持目录中的文件应该由Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}包含。对吗? - big_geron
你肯定忘了加上 :type => :controller 这一部分。我刚刚去掉它,得到了同样的错误。 - jibiel
我得到了相同的错误。使用 :type => :controller 也没有关系。 - big_geron
我在升级到rspec后遇到了相同的错误,看起来是rspec API发生了变化? - Ian Yang
1个回答

9

我曾经也遇到了完全相同的问题,在搜索一番之后,我发现直接包含Warden::Test::Helpers是一个更为简洁的解决方案,因为它可以在请求规范中自动地登录/注销用户,就像这样:

# spec/support/request_helpers.rb
require 'spec_helper'
include Warden::Test::Helpers

module RequestHelpers
  def create_logged_in_user
    user = Factory(:user)
    login(user)
    user
  end

  def login(user)
    login_as user, scope: :user
  end
end

简而言之,只需包含Warden :: Test :: Helpers,然后使用login_as <your_user>方法即可!
解决方案取自此处:http://simple10.com/rspec-capybara-devise-login-tests/

2
另外,请注意,如果您像这样描述控制器类:describe NewsController ... 而不是 ... describe "NewsController",那么 Devise::TestHelpers 只能正常工作。 - gato_omega

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接