7

Railscast on Devise と OmniAuth に従ってOmniauthCallbacksController < Devise::OmniauthCallbacksControllerOmniAuth コールバックを処理する単一のメソッドを含むを実装しました。

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

ルート.rb:

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

これをカスタマイズしたいので、RSpecを使ってテストしようとしています。問題は、このメソッドとリダイレクトをどのようにテストするかです。

仕様に記載されている場合user_omniauth_callback_path(:facebook)、ルートが存在しないことについて不平を言うことはありませんが、実際にメソッドを呼び出しているようには見えません。

この回答によると、 「コントローラーのテストでは、コントローラーが RESTful であるかどうかに関係なく、4 つの HTTP 動詞 (GET、POST、PUT、DELETE) を使用します。」などを試しget user_...ましたが、ここではルートが存在しないと文句を言います。実際、私が行うrake routesと、このルートに HTTP 動詞がないことが示されます。

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

私が欠けているものを見ることができますか?

編集

したがって、この質問に続いて、メソッドを呼び出す1つの方法は次のとおりです。

controller.send(:all)

ただし、質問者が遭遇したのと同じエラーが発生します。

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

3 に答える 3

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
于 2016-05-21T01:42:05.310 に答える
1

の身もだえRSpecの問題が発生OmniauthCallbacksControllerしています。これについて調査すると、うまくいきます。誰かが必要だと思った場合、これが私のコードです。テストはハッピーパス用であり、のニュースバージョンで機能するはずです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
于 2015-09-04T07:50:59.030 に答える