4

我有带有 Grape API 的 Rails 应用程序。

该接口由 Backbone 完成,Grape API 为其提供所有数据。

它返回的只是用户特定的东西,所以我需要参考当前登录的用户。

简化版如下所示:

API初始化:

module MyAPI
  class API < Grape::API
    format :json

    helpers MyAPI::APIHelpers

    mount MyAPI::Endpoints::Notes
  end
end

端点:

module MyAPI
  module Endpoints
    class Notes < Grape::API
      before do
        authenticate!
      end

      # (...) Api methods
    end
  end
end

API 助手:

module MyAPI::APIHelpers
  # @return [User]
  def current_user
    env['warden'].user
  end

  def authenticate!
    unless current_user
      error!('401 Unauthorized', 401)
    end
  end
end

所以,正如你所看到的,我从 Warden 那里得到了当前用户,它工作正常。但问题在于测试。

describe MyAPI::Endpoints::Notes do
  describe 'GET /notes' do
    it 'it renders all notes when no keyword is given' do
      Note.expects(:all).returns(@notes)
      get '/notes'
      it_presents(@notes)
    end
  end
end

如何使用某些特定用户存根助手的方法 *current_user*?

我试过了:

  • 设置 env/request,但在调用get方法之前它不存在。
  • 使用 Mocha 存根 MyAPI::APIHelpers#current_user 方法
  • 使用 Mocha 存根 MyAPI::Endpoints::Notes.any_instance.stub

编辑:目前,它是这样存根的:

规格:

  # (...)
  before :all do
    load 'patches/api_helpers'
    @user = STUBBED_USER
  end
  # (...)

规范/补丁/api_helpers.rb:

STUBBED_USER = FactoryGirl.create(:user)
module MyAPI::APIHelpers
  def current_user
    STUBBED_USER
  end
end

但这绝对不是答案:)。

4

2 回答 2

2

这个问题中提到的评论应该对你有帮助,这就是 Grape 测试它的助手的方式,

https://github.com/intridea/grape/blob/master/spec/grape/endpoint_spec.rb#L475 (如果代码由于更改而不在同一行,只需执行 ctrl+f 并寻找帮助)

这是来自同一文件的一些代码

it 'resets all instance variables (except block) between calls' do
  subject.helpers do
    def memoized
      @memoized ||= params[:howdy]
    end
  end

  subject.get('/hello') do
    memoized
  end

  get '/hello?howdy=hey'
  last_response.body.should == 'hey'
  get '/hello?howdy=yo'
  last_response.body.should == 'yo'
end
于 2013-09-09T11:17:52.917 回答
0

选项1

推荐的方法是使用Grape::Endpoint.before_each

context 'when user is logged in' do
  before do
    Grape::Endpoint.before_each do |endpoint|
      allow(endpoint).to receive(:current_user).and_return(user)
    end
  end

  after { Grape::Endpoint.before_each nil }
end

但这很冗长。它可以存在于共享上下文中,但您不能user明确地作为参数传递,因此您最终会得到:

let(:user) { create(:user) }
# ...
include_context 'signed in user'

选项 2

我首选的方法是更像 RSpec 的存根:

# helper
module AuthHelper
  def current_user
    # ...
  end
end

# api
module API
  module V1
    class Auth < Grape::API
      helpers AuthHelper
    end
  end
end

# spec
before do
  allow_any_instance_of(AuthHelper).to receive(:current_user).and_return(user)
end

选项 3

您还可以定义助手

API::V1::User.helpers do
  def current_user
    user
  end
end
于 2022-03-01T10:08:28.400 回答