2013-05-08 7 views
7

में पुनर्निर्देश मैं एक OmniauthCallbacksController < Devise::OmniauthCallbacksController जो एक OmniAuth कॉलबैक संभालने के लिए एकल विधि शामिल लागू किया है Railscast on Devise and OmniAuth के बाद:Rspec: टेस्ट वसीयत :: OmniauthCallbacksController उपवर्ग

def all 
    user = User.from_omniauth(request.env["omniauth.auth"]) 
    if user.persisted? 
    sign_in_and_redirect user 
    else 
    session["devise.user_attributes"] = user.attributes 
    redirect_to new_user_registration_url 
    end 
end 
alias_method :facebook, :all 

routes.rb:

devise_for :users, controllers: {omniauth_callbacks: "omniauth_callbacks", :sessions => "sessions" } 

मैं इसे कस्टमाइज़ करना चाहता हूं, इसलिए मैं आरएसपीईसी का उपयोग करके इसका परीक्षण करने की कोशिश कर रहा हूं। सवाल यह है कि मैं इस विधि और रीडायरेक्ट का परीक्षण कैसे करूं?

यदि spec में मैंने user_omniauth_callback_path(:facebook) डाल दिया है तो यह उस मार्ग के बारे में शिकायत नहीं करता है जो मौजूदा नहीं है, लेकिन वास्तव में विधि को कॉल नहीं करता है।

this answer के अनुसार "नियंत्रक परीक्षण चार HTTP क्रियाएं (GET, POST, PUT, DELETE) का उपयोग करते हैं, भले ही आपका नियंत्रक रीस्टफुल है या नहीं।" मैंने get user_... इत्यादि की कोशिश की लेकिन यहां यह शिकायत करता है कि मार्ग मौजूद नहीं है। और वास्तव में यह पता चलता है इस मार्ग के लिए कोई HTTP क्रिया होती है अगर मैं rake routes कार्य करें:

user_omniauth_callback [BLANK] /users/auth/:action/callback(.:format) omniauth_callbacks#(?-mix:facebook) 

आप देख सकते हैं कि मैं क्या याद कर रहा हूँ?

संपादित

तो विधि बुलाने की this question एक तरह से पीछा कर रहा है:

controller.send(:all) 

हालांकि मैं तो एक ही त्रुटि प्राप्त है कि प्रश्नकर्ता में भाग:

ActionController::RackDelegation#content_type delegated to @_response.content_type, but @_response is nil 

उत्तर

5

इसे पूरा करने के लिए आपको तीन चीजें करने की आवश्यकता होगी।

  • OmniAuth परीक्षण वातावरण
  • दर्ज बाहर अपने from_omniauth विधि एक OmniAuth परीक्षण नकली
  • ठूंठ बनाने के लिए एक उपयोगकर्ता

यहाँ एक संभव समाधान है वापस जाने के लिए, कल्पना ही (कल्पना में प्रवेश किया उदाहरण के लिए /feature/login_spec.rb)। । ।

let(:current_user) { FactoryGirl.create(:user) } 

before do 
    OmniAuth.config.test_mode = true 
    OmniAuth.config.mock_auth[:facebook] = OmniAuth::AuthHash.new({ 
    provider: :facebook, 
    uid:'12345', 
    info: { 
     name: "Joe" 
    } 
    }) 
    User.stub(:from_omniauth).and_return(current_user) 
end 

मैं एक गूगल प्रमाणीकरण से अनुकूलित है, तो फेसबुक अधिक क्षेत्रों की आवश्यकता हो सकती है, लेकिन उन लोगों को केवल required by omniauth docs हैं। आपको अपने डेटाबेस स्कीमा को देखकर और फ़ील्ड को मेल खाने वाले फ़ील्ड ढूंढकर सही फ़ील्ड ढूंढने में सक्षम होना चाहिए।

मेरे मामले में, न्यूनतम अनुरोध अनुरोध चरण पारित करने के लिए पर्याप्त था और मेरे उपयोगकर्ता को वापस करने वाली स्टब किए गए विधि पर आगे बढ़ना था।

यह उदाहरण FactoryGirl का भी उपयोग करता है।

यह सही नहीं हो सकता है, लेकिन मुझे उम्मीद है कि यह मदद करता है। सौभाग्य!

-Dan

+0

बिल्कुल सही। कई स्तरों पर सहायक, कम से कम मैं इस बारे में एक फीचर स्पेक की बजाय नियंत्रक स्पेक के रूप में सोच रहा था। बहुत सराहना की! –

+1

मदद करने के लिए खुशी हुई! यह मुझे डेढ़ घंटे तक मेरे घुटनों पर लाया। मुझे खुशी है कि कोई और मेरी निराशा से लाभ उठा सकता है! वाक्यविन्यास बहुत दूर था? यदि ऐसा है, तो कृपया सही समाधान के साथ संपादित करें। धन्यवाद! –

+1

वाक्यविन्यास पूरी तरह से काम किया। मेरे द्वारा किए गए एकमात्र परिवर्तन spec_helper.rb में थोड़ा सा खींच रहा था [इस उत्तर] (http://stackoverflow.com/a/9915796/1450420) जो मुझे आपके उत्तर के लिए धन्यवाद मिला। –

1

मैं OmniauthCallbacksController के लिए RSpec writhing के लिए समस्या का सामना कर रहा हूँ, इस पर कुछ शोध करते हैं और यह मेरे लिए काम कर रहे। यदि कोई आवश्यक हो तो यहां मेरे कोड हैं। टेस्ट खुश पथ के लिए कर रहे हैं और आप इस हिट यदि यह RSpec eg. 3.x

require 'spec_helper' 

    describe OmniauthCallbacksController, type: :controller do 
     describe "#linkedin" do 
     let(:current_user) { Fabricate(:user) } 

     before(:each) do 
      OmniAuth.config.test_mode = true 
      OmniAuth.config.mock_auth[:linkedin] = OmniAuth::AuthHash.new({provider: :linkedin, uid: '12345', credentials: {token: 'linkedin-token', secret: 'linkedin-secret'}}) 
      request.env["devise.mapping"] = Devise.mappings[:user] 

      @controller.stub!(:env).and_return({"omniauth.auth" => OmniAuth.config.mock_auth[:linkedin]}) 
      User.stub(:from_auth).and_return(current_user) 
     end 

     describe "#linkedin" do 
      context "with a new linkedin user" do 
      before { get :linkedin } 

      it "authenticate user" do 
       expect(warden.authenticated?(:user)).to be_truthy 
      end 

      it "set current_user" do 
       expect(subject.current_user).not_to be_nil 
      end 

      it "redirect to root_path" do 
       expect(response).to redirect_to(root_path) 
      end 
      end 
     end 

     end 
    end 
+0

क्या आपने इसे rspec 3.4 में काम करने के लिए समायोजित किया है? –

+0

हां समायोजित और संपादित किया गया। –

3

की खबर संस्करण के लिए काम करना चाहिए और आप चल रहे हैं rspec 3.4 इस उदाहरण आप के लिए काम करना चाहिए:

describe Users::OmniauthCallbacksController, type: :controller do 
    let(:current_user) { FactoryGirl.create(:user) } 

    before do 
    OmniAuth.config.test_mode = true 
    OmniAuth.config.mock_auth[:your_oauth_provider_here] = OmniAuth::AuthHash.new(
     provider: :your_oauth_provider_here, 
     uid: rand(5**10), 
     credentials: { token: ENV['CLIENT_ID'], secret: ENV['CLIENT_SECRET'] } 
    ) 
    request.env['devise.mapping'] = Devise.mappings[:user] 
    allow(@controller).to receive(:env) { { 'omniauth.auth' => OmniAuth.config.mock_auth[:your_oauth_provider_here] } } 
    allow(User).to receive(:from_omniauth) { current_user } 
    end 

    describe '#your_oauth_provider_here' do 
    context 'new user' do 
     before { get :your_oauth_provider_here } 

     it 'authenticate user' do 
     expect(warden.authenticated?(:user)).to be_truthy 
     end 

     it 'set current_user' do 
     expect(current_user).not_to be_nil 
     end 

     it 'redirect to root_path' do 
     expect(response).to redirect_to(root_path) 
     end 
    end 
    end 
end