- 更新日: 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 で複数のホストで共通のテストを使い回す
Leave Your Message!