【问题标题】:Access to request object in request specs访问请求规范中的请求对象
【发布时间】:2014-04-03 23:32:12
【问题描述】:

如何在根据请求规范执行请求之前设置请求标头?

我正在使用 Rails 移动控制器规范以在我的 API 上请求规范。我坚持的一件事是我无法访问 request 对象来允许请求。

根据我的控制器规格,我可以访问我创建的一种方法,该方法为特定用户签名:

def sign_in(user)
  token = user.api_keys.first.token
  # note the request object being used in the next line
  request.env["HTTP_AUTHORIZATION"] = ActionController::HttpAuthentication::Token.encode_credentials(token)
end

这在控制器规格上运行良好,我可以安全地这样做:

before { sign_in(user) }
it { post :endpoint, params }

但在请求规范中,request 对象不可用。 如果我尝试:

before { sign_in(user) }
it { post "/api/endpoint", params }

我在我的辅助方法中得到request nil

我知道我能做到:

it { post "/api/endpoint", {"HTTP_AUTHORIZATION" => ... } }

但这在规范中似乎很混乱,特别是与控制器规范相比。

按照this answer 的建议,我已尝试使用ActionDispatch::TestRequest::DEFAULT_ENV,但也没有用(我得到了401)。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4 rspec rspec-rails


    【解决方案1】:

    如果您还没有为此使用Rack::Test,那么您应该使用。 Rack::Test 比 Capybara 更适合测试 API 请求。可以在你的rspec/spec_helper.rb进行配置

    RSpec.configure do |config|
      # ...
      config.include Rack::Test::Methods
    end
    

    当您配置为使用 Rack::Test 时,您可以像这样在请求之前设置标头:

    it 'POST /api/enpoint authenticates successfully' do
      header 'Authorization', '...'
      post "/api/endpoint", params
      expect(last_response).to be_ok
    end
    

    这将在您的控制器中作为request.headers['HTTP_AUTHORIZATION'] 访问。

    这个方法的源代码可以在这里找到-https://github.com/brynary/rack-test/blob/master/lib/rack/test.rb#L127-L141

    【讨论】:

    • 这是在 rspec 文档中的任何地方指定的吗?
    【解决方案2】:

    如果您使用 capybara 作为请求规范,我想您可以设置像建议的 here 这样的标题,但是最好通过 HTML 表单或任何在您的应用程序中进行身份验证的方式执行真正的登录,因为请求规范比控制器的规范更高,这就是为什么它们通常不允许您手动设置标头、cookie 和其他低级别的东西。

    【讨论】:

    • 这是一个 API,它只输出 JSON,而不是最终用户正在与之交互的东西。
    猜你喜欢
    • 1970-01-01
    • 2012-09-15
    • 2011-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-20
    • 2020-11-04
    • 2011-10-18
    相关资源
    最近更新 更多