使用rspec测试Devise和OmniAuth与Twitter的集成

4

我正在尝试使用OmniAuth和Devise编写与Twitter签入相关的集成测试。我在设置请求变量时遇到了困难。它可以在控制器测试中工作,但不能在集成测试中工作,这让我认为我没有正确配置spec helper。我已经查找过,但似乎找不到可行的解决方案。以下是我目前的代码:

# spec/integrations/session_spec.rb
require 'spec_helper'
describe "signing in" do
  before do
    request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:twitter]
    visit new_user_session_path
    click_link "Sign in with twitter"
  end

  it "should sign in the user with the authentication" do
    (1+1).should == 3
  end
end

在测试之前,这个规范就会产生错误,我不太确定request变量需要在哪里初始化。错误信息如下:

Failure/Error: request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:twitter]
  NoMethodError:
    undefined method `env' for nil:NilClass

现在我在控制器规范中使用request变量,测试通过了,但是它没有被初始化用于集成测试。

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

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

感谢您的帮助!
4个回答

3

Capybara README 表示:“测试中无法访问会话和请求”,因此我放弃了在测试中进行配置,并决定在 application_controller.rb 中编写帮助方法。

before_filter :set_request_env
def set_request_env
  if ENV["RAILS_ENV"] == 'test'
    request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:twitter] 
  end
end

2

Devise测试助手仅适用于控制器规范(specs),而不是集成规范(integration specs)。在capybara中没有请求对象,因此设置它不起作用。

相反,您应该将Devise测试助手的加载范围限定在控制器规范中,类似于以下内容:

class ActionController::TestCase
  include Devise::TestHelpers
end

按照这个指南建议,在capybara规范中使用warden助手: https://github.com/plataformatec/devise/wiki/How-To:-Test-with-Capybara

有关更详细的讨论,请查看此Github问题页面:https://github.com/nbudin/devise_cas_authenticatable/issues/36


2

这个方法在我的测试中使用rspec + devise + omniauth + omniauth-google-apps时有效。毫无疑问,Twitter的解决方案也会非常相似:

# use this method in request specs to sign in as the given user.
def login(user)
  OmniAuth.config.test_mode = true
  hash = OmniAuth::AuthHash.new
  hash[:info] = {email: user.email, name: user.name}
  OmniAuth.config.mock_auth[:google_apps] = hash

  visit new_user_session_path
  click_link "Sign in with Google Apps"
end

0

当使用较新版本的RSpec进行请求规范时,无法访问请求对象:

before do
  Rails.application.env_config["devise.mapping"] = Devise.mappings[:user] # If using Devise
  Rails.application.env_config["omniauth.auth"] = OmniAuth.config.mock_auth[:twitter]
end

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