RSpec设计sign_in没有在控制器中设置current_user

时间:2014-12-04 05:51:02

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

我已按照以下说明进行操作: Devise wiki使用RSpec设置控制器测试,但我的测试失败了。

而不是呈现页面,它似乎重定向到http://test.host

以下是回复中的一些内容:

@current_user=nil
@_response_body=["<html><body>You are being <a href=\"http://test.host/\">redirected</a>.</body></html>"]

我的测试控制器规范如下:

require 'rails_helper' require 'devise'

RSpec.describe Services::MyController, :type => :controller do   
  include Devise::TestHelpers   
  include Warden::Test::Helpers   

  describe "administrator" do
    before :each do
      @request.env["devise.mapping"] = Devise.mappings[:user]
      #administrator wraps user and adds role
      @admin = FactoryGirl.create(:administrator)
      @admin.confirm!
      sign_in @admin
    end
    describe "GET index" do
      it "returns http success" do
        #puts current_user.to_yaml
        get :index
        expect(response).to be_success
      end
    end   
  end 
end

看起来它会自动重定向到test.host(不知道它来自哪里)因为当前没有用户定义?

在我的应用程序控制器中,我有代码设置,如果用户在其他地方登录,则将用户注销。这似乎是用户被自动重定向的位置。通过在此处转储current_user,我可以看到&#39; current_sign_in_ip&#39;是零,因为没有设置所有其他登录属性。

的ApplicationController

def check_request_ip
    puts current_user.to_yaml
    puts request.remote_ip
    unless current_user.nil? || request.remote_ip == current_user.current_sign_in_ip
      Rails.logger.warn "User already logged in from #{current_user.current_sign_in_ip} and trying to log in from #{request.remote_ip}."
      sign_out_and_redirect(current_user)
    end
  end

rails_helper.rb

ENV["RAILS_ENV"] ||= 'test'
require 'spec_helper'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'

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

ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)

RSpec.configure do |config|

  config.fixture_path = "#{::Rails.root}/spec/fixtures"

  config.use_transactional_fixtures = true

  config.infer_spec_type_from_file_location!
end

spec_helper.rb

require 'factory_girl'
require 'devise'
RSpec.configure do |config|
  begin
    config.include Warden::Test::Helpers
    config.include Devise::TestHelpers, :type => :controller
    config.include FactoryGirl::Syntax::Methods

    config.filter_run :focus
    config.run_all_when_everything_filtered = true

    if config.files_to_run.one?
      config.default_formatter = 'doc'
    end
    config.profile_examples = 10

    config.order = :random

    Kernel.srand config.seed

    config.expect_with :rspec do |expectations|
      expectations.syntax = [:expect, :should]
    end

    config.mock_with :rspec do |mocks|
      mocks.syntax = :expect
      mocks.verify_partial_doubles = true
    end
  end
end

test.rb

Go2Asset::Application.configure do

  config.stretches = Rails.env.test? ? 1 : 10
  config.cache_classes = true

  config.eager_load = false

  config.serve_static_assets = true
  config.static_cache_control = "public, max-age=3600"

  config.consider_all_requests_local = true
  config.action_controller.perform_caching = false

  config.action_dispatch.show_exceptions = false

  config.action_controller.allow_forgery_protection = false

  config.action_mailer.delivery_method = :test
  config.action_mailer.default_url_options = { :host => 'localhost:3000' }

  config.active_support.deprecation = :stderr
end

1 个答案:

答案 0 :(得分:-1)

因为你不需要描述两个描述,因为它们是彼此独立的(它们是两种不同的场景),这就是为什么current_user在第二个描述中为零

尝试定义用于创建用户并签名的方法,您可以通过在support / devise.rb中创建方法来实现,如下所示:

module ControllerMacros
  def login_user
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:user]
      user = FactoryGirl.create(:user) # in factories.rb you should create a factory for 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

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

然后删除第一个描述,在第二个描述中只需写入get:index

login_user

另一种解决方案是首先对login_user进行嵌套描述,如下所示:

describe "something" do
  login_user
  describe "something 1" do
    #yourcode
  end

end