rspec&设计测试助手

时间:2011-06-19 16:33:31

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

根据设计维基的this,我应该能够在我的控制器测试中使用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 设计1.3.4

backtrace

4 个答案:

答案 0 :(得分:18)

我想这种方法存在一些问题。首先,您使用的是请求规范,而不是控制器规范,因此login_user无法使用config.extend ControllerMacros, :type => :controller方法。其次,即使您能够包含该方法,它也很可能无论如何都不会起作用,因为Devise测试助手是专门为控制器/视图测试编写的,而不是集成测试。

看看David Chelimsky的answerthis SO question,这可能会有所帮助。

答案 1 :(得分:4)

我无法肯定回答......但代码味道对我来说就是帮助器中定义的“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

编辑:

看起来您可能需要包含设计测试助手。 rdoc表示您应该拥有此文件:

# spec/support/devise.rb
RSpec.configure do |config|
  config.include Devise::TestHelpers, :type => :controller
end

不确定这是否与您在spec_helper.rb中已经获得它的方式不同 ......看起来和我很相似。

答案 2 :(得分:0)

我在Rails 3.0.10上遇到了同样的问题rspec 2.6.0在我的控制器规格上设计了1.3.4 spork-0.9.0.rc9,我已将config. extend更改为config.include及其工作!

答案 3 :(得分: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