【问题标题】:Rails rspec and omniauth (integration testing)Rails rspec 和omniauth(集成测试)
【发布时间】:2012-03-16 02:07:03
【问题描述】:

My Rails 3.2 应用程序使用 OmniAuth 和 Devise 通过 Twitter 登录。身份验证系统工作正常。我想在 rspec 中编写一个集成测试以确保一切正常。使用 wiki 中的信息,我编写了以下内容,但我知道我遗漏了一些东西。

在 config/environments 中的 test.rb 下,我有以下几行

OmniAuth.config.test_mode = true
OmniAuth.config.mock_auth[:twitter] = {:provider => 'twitter', :uid => '123545'}

我的 rspec 测试如下所示:

describe "Authentications" do
  context "without signing into app" do

    it "twitter sign in button should lead to twitter authentication page" do
      visit root_path
      click_link "Sign in with Twitter"
      Authentication.last.uid.should == '123545'
    end

  end
end

Authentication 是我的模型的名称,在 rails 控制台中调用 .uid 会返回正确的字符串。

我在运行此测试时收到以下错误:

Failure/Error: Authentication.last.uid.should == '123545'
NoMethodError:
undefined method `uid' for nil:NilClass

谁能帮我弄清楚如何使用提供的 OmniAuth 模拟?对于为什么如何它的工作原理的解释也将不胜感激。

【问题讨论】:

    标签: ruby-on-rails-3 rspec integration-testing omniauth rspec-rails


    【解决方案1】:

    我遇到了类似的事情。

    从使用符号键更改我的模拟对象后:

    OmniAuth.config.mock_auth[:twitter] = {
        :uid => '1337',
        :provider => 'twitter',
        :info => {
          :name => 'JonnieHallman'
        }
      }
    

    使用字符串键:

    OmniAuth.config.mock_auth[:twitter] = {
        'uid' => '1337',
        'provider' => 'twitter',
        'info' => {
          'name' => 'JonnieHallman'
        }
      }
    

    成功了。

    你有吗

      request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:twitter] 
    

    在您的测试用例中的某个地方?

    【讨论】:

    • 您好!我尝试了 request.env [“omniauth.auth”],但我收到错误“nil 类的未定义方法 env”
    【解决方案2】:

    您是否尝试将这两行移至 spec_helper.rb?

    OmniAuth.config.test_mode = true
    OmniAuth.config.mock_auth[:twitter] = {:provider => 'twitter', :uid => '123545'}
    

    在您的测试文件中添加以下 before 块:

    before do 
        request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:twitter] 
    end
    

    您可以在此链接上找到更多信息:https://github.com/intridea/omniauth/wiki/Integration-Testing

    【讨论】:

      【解决方案3】:

      我强烈建议this answer

      总之……

      • 设置模拟
      • 提出请求
      • 测试附加到回调的任何代码

      例如:测试 session['uid'] 是否已设置(虽然,我选择只测试用户看到的,或者更确切地说,看不到的)

      我的代码...

      config/environments/test.rb

      Rails.application.configure do
        ...
          OmniAuth.config.test_mode = true
          OmniAuth.config.mock_auth[:linkedin] = { 
            'provider' => 'linkedin', 
            'uid' => '123545', 
            'info'=>
            { 'email'=>'infinite@jest.com',
              'first_name'=>'Dave',
              'last_name'=>'Wallace' }
          }
      end
      

      spec/features/sign_in_feature_spec.rb

      require 'rails_helper'
      
      feature 'Sign in with LinkedIn' do
      
        before do 
          OmniAuth.config.add_mock(:linkedin, {:uid => '12345'})
        end
      
        let(:user) { create(:user) } 
      
        scenario 'with valid email and password' do
          visit '/'
          expect(page).to have_no_content 'Sign Out'
          click_link 'nav-sign-in' # image/button: Sign in with LinkedIn
          expect(page).to have_content 'Sign Out'
        end
      end    
      

      让我知道是否/如何改进此解决方案(以及我的代码!)

      【讨论】:

        【解决方案4】:

        选定的解决方案对我不起作用。 我的解决方案来自https://gist.github.com/kinopyo/1338738 和官方文档https://github.com/intridea/omniauth/wiki/Integration-Testing 这里:

        # in spec/support/omniauth_macros.rb
        module OmniauthMacros
          def mock_auth_hash
            # The mock_auth configuration allows you to set per-provider (or default)
            # authentication hashes to return during integration testing.
            OmniAuth.config.mock_auth[:odnoklassniki] = OmniAuth::AuthHash.new({
                 :provider => 'odnoklassniki',
                 :uid => '123545',
                 :info => OmniAuth::AuthHash::InfoHash.new({
                     :name => 'mockuser'
                 })
             })
        
          end
        end
        
        # in spec/spec_helper.rb
        RSpec.configure do |config|
        
          # email spec
          config.include(EmailSpec::Helpers)
          config.include(EmailSpec::Matchers)
        end
        OmniAuth.config.test_mode = true
        
        # in spec example:
        visit new_user_registration_path
        mock_auth_hash
        find('#btn-odnoklassniki').click # here is link generated as omniauth_authorize_path(resource_name, provider)
        

        【讨论】:

        • 感谢您指向 AuthHash.new(尽管它在集成测试网页中),如果我有包含真正秘密的授权模型的 FactoryGirl,我只能设法让它与考拉一起使用和令牌(例如,从有效的 facebook 登录转换复制和粘贴)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多