Techioz Blog

RSpec リクエストスペックは空の配列をポストします

概要

現在、Rails で API エンドポイントを開発しています。必要なデータが無効な場合、エンドポイントが正しいエラーステータスで応答することを確認したいと考えています。 ID の配列が必要です。無効な値の 1 つは空の配列です。

{ vendor_district_ids: [2, 4, 5, 6]}
{ vendor_district_ids: []}

したがって、動作を制御するためのリクエスト仕様が必要です。

require 'rails_helper'

RSpec.describe Api::PossibleAppointmentCountsController, type: :request do
  let(:api_auth_headers) do
    { 'Authorization' => 'Bearer this_is_a_test' }
  end

  describe 'POST /api/possible_appointments/counts' do
    subject(:post_request) do
      post api_my_controller_path,
        params: { vendor_district_ids: [] },
        headers: api_auth_headers
    end

    before { post_request }

    it { expect(response.status).to eq 400 }
  end
end

ご覧のとおり、件名ブロック内のパラメータで空の配列を使用しています。

私のコントローラーではデータをフェッチしています

params.require(:vendor_district_ids)

値は次のとおりです

<ActionController::Parameters {"vendor_district_ids"=>[""], "controller"=>"api/my_controller", "action"=>"create"} permitted: false>

Vendor_district_ids の値は、空の文字列を含む配列です。 postman で投稿するときは同じ値がありません。

投稿したら

{ "vendor_district_ids": [] }

コントローラーが受信します

<ActionController::Parameters {"vendor_district_ids"=>[], "controller"=>"api/my_controller", "action"=>"create"} permitted: false>

そして、これは空の配列です。

リクエスト仕様内で何か間違ったことをしているのでしょうか、それともこれは RSpec のバグなのでしょうか?

解決策

答えが見つかりました!

問題は、前の回答が示しているように、実際にはrack-test内ではなく、Rackのquery_parser内で見つかりました。

“paramName[]= から {”paramName”:[“”]} への実際の変換は、Rack の query_parser で行われます。

問題の例:

post '/posts', { ids: [] }
{"ids"=>[""]} # By default, Rack::Test will use HTTP form encoding, as per docs: https://github.com/rack/rack-test/blob/master/README.md#examples

「require ’json」を使用して JSON gem をアプリケーションに要求し、param ハッシュに .to_json を追加することで、params を JSON に変換します。

RSPEC リクエストで、このリクエストのコンテンツ タイプが JSON であることを指定します。

上記の例を変更した例:

post '/posts', { ids: [] }.to_json, { "CONTENT_TYPE" => "application/json" }
{"ids"=>[]} # explicitly sending JSON will work nicely