7

在设计和 OmniAuth 上的Railscast 之后,我实现了一个OmniauthCallbacksController < Devise::OmniauthCallbacksController包含单个方法来处理 OmniAuth 回调的方法:

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)说它不会抱怨路由不存在,但似乎并没有真正调用该方法。

根据这个答案“控制器测试使用四个 HTTP 动词(GET、POST、PUT、DELETE),无论您的控制器是否是 RESTful。” 我试过get user_...等,但在这里它确实抱怨路线不存在。事实上,如果我这样做rake routes表明这条路线没有 HTTP 动词:

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

你能看到我错过了什么吗?

编辑

因此,按照这个问题调用该方法的一种方法是:

controller.send(:all)

但是,我遇到了提问者遇到的相同错误:

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

3 回答 3

5

你需要做三件事来完成这项工作。

  • 进入OmniAuth测试环境
  • 创建 OmniAuth 测试模拟
  • 存根 from_omniauth 方法以返回用户

这是一个可能的解决方案,在规范本身中输入(例如,spec/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

我从 google 身份验证中对此进行了调整,因此 facebook 可能需要更多字段,但这些是omniauth docs唯一需要的字段。您应该能够通过查看数据库架构并查找与文档匹配的字段来找到正确的字段。

在我的情况下,最小值足以通过请求阶段并转移到返回我的用户的存根方法。

此示例还使用FactoryGirl

它可能并不完美,但我希望它有所帮助。祝你好运!

-担

于 2013-05-15T21:34:50.897 回答
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 回答