Rails の functionals なテストで JSON を POST/PUT する方法
Rails4 で、JSON を受け取る API を作りました。
早速、テスト書くぞー!と意気込んだものの、はて。JSON ってどうやって投げればいいんだろう。
いろいろ検索して試してみたものの、うまくいくまで時間がかかったので、メモ。
うまくいったやり方
put :update, user: { name: 'HOGE', mofu: 333, moffu: { mofu: 12, bar: true, foo: 'HI' } }, foobar: true, barfoo: { mofu: 3 }, format: :json assert_equal( 'HOGE', User.first.name ) # params => {"user"=>{"name"=>"HOGE", "mofu"=>333, "moffu"=>{"mofu"=>12, "bar"=>true, "foo"=>"HI"}}, "foobar"=>true, "barfoo"=>{"mofu"=>3}, "format"=>"json", "controller"=>"api/user", "action"=>"update"}
ポイント
- POST するオブジェクトを { } でくくってはいけない。
- 最後の引数に format: :json を書く。
ダメだった例1 第2引数を { } でくくる
put :update, { user: { name: 'HOGE', mofu: 333, moffu: { mofu: 12, bar: true, foo: 'HI' } }, foobar: true, barfoo: { mofu: 3 } }, format: :json assert_equal( 'HOGE', User.first.name ) # params => {"user"=>{"name"=>"HOGE", "mofu"=>"333", "moffu"=>{"mofu"=>"12", "bar"=>true, "foo"=>"HI"}}, "foobar"=>true, "barfoo"=>{"mofu"=>"3"}, "controller"=>"api/user", "action"=>"update"}
一見、うまくいっているように見えるが、何故か数字だけが文字列になってしまっています。
JSONのソースを見てみたりと、いろいろ調べたものの、何故か分からず....
ダメだった例2 JSON文字列で渡してみる。
put :update, 'user: { name: 'HOGE', mofu: 333, moffu: { mofu: 12, bar: true, foo: 'HI' } }, foobar: true, barfoo: { mofu: 3 }', :type => :json assert_equal( 'HOGE', User.first.name ) # params => {"type"=>"json", "controller"=>"api/user", "action"=>"update"}
渡らない。
ダメだった例3 タイプだけ変えてみる。
put :update, user: { name: 'HOGE', mofu: 333, moffu: { mofu: 12, bar: true, foo: 'HI' } }, foobar: true, barfoo: { mofu: 3 }, :type => :json assert_equal( 'HOGE', User.first.name ) # params => {"user"=>{"name"=>"HOGE", "mofu"=>"333", "moffu"=>{"mofu"=>"12", "bar"=>true, "foo"=>"HI"}}, "foobar"=>true, "barfoo"=>{"mofu"=>"3"}, "controller"=>"api/user", "action"=>"update"}
数値が文字列になる。
ダメだった例4 最後の引数を消す
put :update, user: { name: 'HOGE', mofu: 333, moffu: { mofu: 12, bar: true, foo: 'HI' } }, foobar: true, barfoo: { mofu: 3 } assert_equal( 'HOGE', User.first.name ) # params => {"user"=>{"name"=>"HOGE", "mofu"=>"333", "moffu"=>{"mofu"=>"12", "bar"=>true, "foo"=>"HI"}}, "foobar"=>true, "barfoo"=>{"mofu"=>"3"}, "controller"=>"api/user", "action"=>"update"}
やはり、数字が文字列になってしまう。
ダメだった例5 直接指定
@request.env["RAW_POST_DATA"] = { user: { name: 'HOGE', mofu: 333, moffu: { mofu: 12, bar: true, foo: 'HI' } }, foobar: true, barfoo: { mofu: 3 } }.to_json @request.env["CONTENT_TYPE"] = 'application/json' put :update assert_equal( 'HOGE', User.first.name ) # params => {"controller"=>"api/user", "action"=>"update"}
パラメータが渡らない。