13

rails-api gemを使用してWebサービスを構築しており、RSpecを使用してAPIをテストしたいと考えています。HTTPメソッドに関係なく、私が行うすべてのリクエストには、CONTENT_TYPE「application/x-www-form-urlencoded」として設定されたヘッダーがあります。これは、コントローラーでwrap_parametersを使用しようとするまでは実際には問題ではなく、paramsハッシュには影響しません。

class ApplicationController < ActionController::API
  include ActionController::ParamsWrapper
end

class ProjectsController < ApplicationController
  wrap_parameters :project, include: [:name]
  # ...
end

このハックは機能しなくなり(@requestはnil)、私が見つけた他のStackOverflowの投稿も機能しません。

RSpecテストで次のリクエストを行った場合:

put "/projects/1.json", {name: 'Updated Project 1'}

デバッガーをコントローラーに配置すると、次のようになります。

(rdb:1) p params
    { "name"=>"Updated Project 1",
  "action"=>"update",
  "controller"=>"projects",
  "id"=>"5539bbd9-010c-4cfb-88d3-82dadbc99507",
  "format"=>"json"
}

(rdb:1) p request.content_type
"application/x-www-form-urlencoded"

paramsハッシュに次のようなものが表示されることを期待しています(プロジェクトキーの追加に注意してください)。

{ "name"=>"Updated Project 1",
  "action"=>"update",
  "controller"=>"projects",
  "id"=>"5539bbd9-010c-4cfb-88d3-82dadbc99507",
  "format"=>"json",
  "project" => {"name" => "Updated Project 1"}
}

RSpecだけでコンテンツタイプヘッダーを設定することはできますか?または、この機能のためにラック/テストを使用する必要がありますか?

4

7 に答える 7

22

多くの欲求不満とバリエーション、そしてそれは私のために働いたものです。 Rails 3.2.12 Rspec 2.10

 @request.env["HTTP_ACCEPT"] = "application/json"
 @request.env["CONTENT_TYPE"] = "application/json"
 put :update, :id => 1, "email" => "bing@test.com"

wrap_parametersはこのように宣言されて機能しているようです

wrap_parameters User, format: :json

Userモデルに使用されている

于 2013-03-26T01:48:56.473 に答える
7

誰かがより新しいバージョンを探しているなら、これは私にとってRails4.0.3Rspec2.14.1でうまくいきました。

put '/projects/1.json', {name: 'Updated Project 1'}, {
  'HTTP_ACCEPT' => 'application/json',
  'CONTENT_TYPE' => 'application/json'
}

wrap_parameters Project, format: :json
于 2014-12-22T20:06:45.180 に答える
5

新しいRailsv5.0.xAPIのみの設定を使用すると、Railsがすべてをデフォルト設定するというこの問題は"application/x-www-form-urlencoded"、RSpec-Railsリクエストを使用したテストでまだ問題になっていることがわかりました。

問題を解決するために私がしたことは次のとおりです。

でサポートファイルを作成します./spec/support/json_requests.rb

これを次のように編集して、すべてのAPIのみのJSONリクエストの動作をオーバーライドします。

module JsonRequests
  def get(*args)
    super(*json_args(*args))
  end

  def post(*args)
    super(*json_args(*args))
  end

  def update(*args)
    super(*json_args(*args))
  end

  def patch(*args)
    super(*json_args(*args))
  end

  def put(*args)
    super(*json_args(*args))
  end

  def delete(*args)
    super(*json_args(*args))
  end

  def json_args(path, params = {}, headers = {})
    [path, params.to_json, headers.merge('CONTENT_TYPE' => 'application/json')]
  end
end

RSpec.configure do |config|
  config.include JsonRequests, type: :request
end

これにより、内のすべての仕様が上書きされることに注意してください。使用する必要がある場合は、ブロック内で必要に応じてこのモジュールを手動で./spec/requests使用"application/x-www-form-urlencoded"することもできます。includeDescribe 'something' do

于 2016-02-09T22:23:23.510 に答える
4

Rails 5ハックなし:

put(:update,
    params: {project_id: 1},
    body: {name: 'Updated Project 1'}.to_json,
    as: :json)

これにより、content_type正しく設定されます。コントローラでparamsは、paramsとbodyの両方を保持します。

于 2019-04-02T15:37:22.580 に答える
2

その2021、Rails 6.1と私は、as: :jsonパラメータ内のハッシュの配列のこの奇妙なマングリングを修正するために使用する必要がありました。

put(:update, params: the_params_hash, as: :json)
于 2021-03-23T04:09:27.133 に答える
0

Rails 4(およびrspec〜3.7)を使用していて、インライン構文を使用したくない場合:

request.headers["CONTENT_TYPE"] = "application/json"
于 2018-01-16T19:08:11.117 に答える
0

Rails 5

headers = { 'CONTENT_TYPE' => 'application/json' }
params = { user_type: 'tester' } 

そしてその後のような要求

post '/api/v1/users/test', params.to_json, headers

.to_jsonまた、リクエストルートから削除します

于 2020-12-25T09:05:14.110 に答える