nil的未定义方法`provider':NilClass,RSpec,OmniAuth

时间:2017-01-04 22:30:22

标签: ruby-on-rails ruby rspec omniauth omniauth-google-oauth2

我正在尝试使用RSpec和OmniAuth测试经过身份验证的控制器。我在他们的维基上遵循了integration testing指南。当我运行测试时,我收到以下错误:

Failure/Error:
       where(provider: auth.provider, uid: auth.uid).first_or_initialize.tap do |user|
        user.provider = auth.provider
        user.uid = auth.uid
        user.first_name = auth.info.first_name
        user.last_name = auth.info.last_name
        user.email = auth.info.email
        user.picture = auth.info.image
        user.save!
       end

     NoMethodError:
       undefined method `provider' for nil:NilClass

gist中提供了所有相关代码。我的预感是模拟auth哈希没有以某种方式设置,但我无法验证。我在config/environments/test.rb中配置了OmniAuth,如Gist中所示,我很确定该文件在应用程序启动时运行。

1 个答案:

答案 0 :(得分:1)

我看到了几个问题。首先,您没有测试登录操作。您正在使用请求中的oauth数据执行控制器操作,并期望它通过身份验证。 Oauth数据不像API密钥,不会让您自动登录。您必须点击omniauth提供的特定登录操作,然后设置您的用户会话。这应该自行测试,以确认您的整个oauth登录策略按预期工作。如果您正在测试与oouth signins行为没有直接关系的控制器操作,那么在运行需要身份验证的测试之前,您应该使用the devise test helpers登录用户。

此外,您不希望在环境初始化程序中设置OmniAuth配置。文档建议,我自己做的是在测试中设置配置。首先,这允许您测试不同类型的场景。例如,这就是我测试我的omniauth回调控制器是如何工作并按照我想要的方式进行测试的方法:

context 'with valid google credentials' do
  # this should actually be created in a factory
  let(:provider) { :google_oauth2 }
  let(:oauth) { OmniAuth::AuthHash.new provider: provider, uid: '1234' }
  before do
    OmniAuth.config.test_mode = true
    OmniAuth.config.mock_auth[provider] = oauth
  end

  it 'creates a new user' do
    expect { visit "/users/auth/#{provider}" }.to change(User, :count).by(1)
  end
end