RSpec和Devise测试助手

18

根据devise的wiki,我应该能够在我的控制器测试中使用login_user帮助方法。因此,在spec目录下我有以下内容:

#spec_helper.rb
...
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}

RSpec.configure do |config|
  config.include Devise::TestHelpers, :type => :controller
  config.extend ControllerMacros, :type => :controller
...

并且

#support/controller_macros.rb
module ControllerMacros    
  def login_user
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:user]
      @user = Factory.create(:user)
      sign_in @user
    end
  end
end

然而调用这个辅助函数没有起作用:

#requests/some_spec.rb
require 'spec_helper'
describe "GET /guides/edit" do
  login_user     
end

有人能指出我的错误所在吗?测试套件工作良好,除了这个问题。我得到一个未定义的本地变量或方法消息,所以我猜测该模块没有被包含。

Rails 3.0.7 rspec 2.6.0 devise 1.3.4

回溯信息


你的 some_spec.rb 文件里是不是打错了?log_in / login_user - Dogbert
1
你得到了什么回溯信息? - Taryn East
嗨。已添加到问题底部。 - mark
等一下——那个回溯正在说它找不到你的login_user方法。我不知道"controller_macros.rb"是什么……但是怎么样直接把它放进spec_helper.rb中看看login_user是否真的有效,然后再想办法包含ControllerMacros以便它能找到你的帮助方法。 - Taryn East
4个回答

18
我想这种方法可能存在几个问题。首先,您正在使用请求规范,而不是控制器规范,因此login_user方法不会通过config.extend ControllerMacros, :type => :controller提供。其次,即使您能够包含该方法,它很可能也无法正常工作,因为Devise测试助手专门编写用于控制器/视图测试,而不是集成测试。
请参阅David Chelimsky对this SO questionanswer,这可能会有所帮助。

谢谢zetetic。你是完全正确的,我混淆了控制器和请求规范。链接的答案完美地解决了问题。 - mark
如何在规范中退出已登录的会话。 - aashish

4

我不能确定,但对于我来说,代码的异味出现在helper内部定义的“before(:each)”上。你为什么不尝试使用以下方法:

#support/controller_macros.rb
module ControllerMacros    
  def login_user
    @request.env["devise.mapping"] = Devise.mappings[:user]
    @user = Factory.create(:user)
    sign_in @user
  end
end

并且

#requests/some_spec.rb
require 'spec_helper'
describe "GET /guides/edit" do
  before(:each) do
    login_user     
  end
end

如果失败了 - 也许它只是找不到 @request - 那么就将它作为一个变量传递给 login_user。
编辑:
看起来你可能需要包含 devise 测试帮助程序。 rdoc 上说你应该有这个文件:
# spec/support/devise.rb
RSpec.configure do |config|
  config.include Devise::TestHelpers, :type => :controller
end

不确定这是否与您在spec_helper.rb中已有的方式不同,对我来说看起来非常相似。


谢谢您的回答。我尝试了那个方法,但总是出现缺少方法变量/错误的提示,这似乎表明模块根本没有被包含进来。 - mark
哦,抱歉,我使用Test::Unit(虽然在另一个项目中我使用rspec),所以我只是猜测...也许你可以在spec_helper.rb中要求'require 'devise''? - Taryn East
1
嗨Taryn,感谢您的建议,但看起来我混淆了控制器规范和请求规范。 - mark

0

忘记确认您的应用程序是否可确认。您的代码应该如下所示

module ControllerMacros
  def login_user
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:user]
      user = FactoryGirl.create(:user)
      #user.confirm! # or set a confirmed_at inside the factory. Only necessary if you are using the confirmable module
      sign_in user
    end
  end
end

0

我在使用Rails 3.0.10、rspec 2.6.0、devise 1.3.4和spork-0.9.0.rc9时遇到了同样的问题,这在我的控制器规范中发生。我已经将config.extend更改为config.include,然后它就起作用了!


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