- 更新日: 2015年7月15日
- RSpec
RSpecでJSONによるPOSTリクエストをテスト
Rails プロジェクトで、生の JSON データをコントローラーのメソッドに POST する RSpec のテストを書きたかったのですが、書き方でとても苦労したので備忘録メモ。
— 環境 —
rails 4.1
rspec-rails 3.1.0
JSON データの POST が Controller Spec で動かない…
最初、テストの性質からしてコントローラーのテスト(spec/controllers/some_controller_spec.rb)に、JSON データを POST するテストを書こうとしました。結果、色んな書き方を試したのですが、どうにも動作しない…。JSON データじゃなくて、パラメータのハッシュを POST する場合は、以下のページの書き方で普通に動きます。
RSpec の ControllerSpec でパラメータとともに post 送信するテスト | EasyRamble
ぐぐりまくって調べたところ、次の stackoverflow ページを発見。
As far as I have been able to tell, sending raw POST data is no longer possible within a controller spec. However, it can be done pretty easily in a request spec:
結果としては、上記ページに書いてある、request spec 内で JSON データを POST する方法で上手く動作させることができました。その下に controller spec に書く方法も書いてありますけど、そっちは試してません。
Request Spec で JSON データを POST するテストコード
SomeController#some_action に、request.body として受け取った JSON データを parse して、その後に SomeModel オブジェクトをDBレコードに保存するような処理が書いてあるという前提です。
app/controllers/some_controller.rb
| 1 2 3 4 5 6 7 8 9 10 11 12 | class SomeController < ApplicationController   # ...   def some_action     json_body = JSON.parse(request.body.read)     # save SomeModel object     # ...   end   # ... end | 
ルーティングは以下のとおり。
config/routes.rb
| 1 | post 'some_controller/some_action' => 'some_controller#some_action' | 
この SomeController#some_action に生の文字列の JSON データを POST して、POST が成功したら SomeModel のレコードが1つ増えるのを確認するテストコードを書きたかった。最終的に書いたのが以下のようなテストコードです。
spec/requests/some_request_spec.rb
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | require 'rails_helper' describe "Post to SomeController#some_action" do   subject { page }   let(:request_header) do     { 'CONTENT_TYPE' => 'application/json', 'ACCEPT' => 'application/json' }   end   describe "with valid json data" do     let(:json_body) do       '{"foo":"foo_value", "bar":"bar_value", "baz":"baz_value"}'     end     it "should increment SomeModel count" do       expect do         # post to /some_controller/some_action         post "/some_controller/some_action", json_body, request_header       end.to change(SomeModel, :count).by(1)     end   end   # ... end | 
この request spec に書く方法で無事に動作させることができ、テストが通るのを確認できました。
- RSpec の関連記事
- FactoryGirlをSpringと共に使う時の注意
- 複数モデルのpost :createをテストするRSpecコード(Controller Spec)
- RSpec3でTime.nowをスタブ化(stub)
- RSpec & Capybara の雑感
- RSpec+Capybaraで同名の複数要素の並び順をテストする
- RSpec3ではrails_helper.rbがrequireされる
- Capybara + Launchy で RSpec テストをブラウザで確認
- CapybaraのwithinをRSpecで使う
- Serverspec(RSpec)のテスト出力に色を付けて見やすくフォーマット
- Serverspec で複数のホストで共通のテストを使い回す

 画像付き英語辞書 Imagict | 英単語をイメージで暗記
画像付き英語辞書 Imagict | 英単語をイメージで暗記









Leave Your Message!