Edited at

【Rails】RSpecでWeb APIのテストでハマったところ①

More than 3 years have passed since last update.

(2014/12/12 追記)

本稿のアップデート版みたいなのをアップしました→『【Rails】RSpecと三種の神器でらくちんWeb APIテスト - Qiita


Railsアプリを作るときに,Web APIのテストをしようとしたら命を落としかけたのでいろいろヤバそうなところをメモっておきますφ(`д´)


JSONレスポンスのテストはすべき?

Everyday Rails - RSpecによるRailsテスト入門では,Viewのテストは取り扱っていません(理由は2章 Q&Aにて).

でもWeb APIのレスポンスはどうなんだろう? ということで訳者のひとりである西脇.rb@jnchitoさんに聞いてみたところ,次のように答えていただきました.

ということで実際にテストを書いていったのですが,たくさんハマったところがあったので共有しておきます.


追記(2014/3/27)

最初はController SpecにJSONのテストを書いていたのですが,Rails API Testing Best Practices With RSpecによると


Use RSpec Request Specs

Since we’ve established that we’ll be using Rack::Test to drive the tests, RSpec request specs make the most sense. There’s no need to get fancy and add extra weight to your testing tools for this.


Request specs provide a thin wrapper around Rails’ integration tests, and are designed to drive behavior through the full stack, including routing (provided by Rails) and without stubbing (that’s up to you).


To test requests and their responses, just add a new request spec. I’ll demonstrate testing a user sessions endpoint. My API returns a token on a successful login.


だそうですので,Request Specで書きなおしました.

JSONレスポンスのテストはRequest Specで書いて,ステータスコードとかのテストをController Specに書けばいいのかな…?


ハマったところ


JSONが返ってこない(missing template編)


内容

とりあえずresponse.bodyのテストをしようとしたところ,まさかのActionView::MissingTemplateが発生….

半日ほど時間を溶かしました.

問題のコードは以下(抜粋).


test_controller_spec.rb

describe 'GET #show' do

it 'returns valid response body' do
get :show, id: @test
expect(response.body).to # ...(略)
end
end


原因・対策

HTTPヘッダにAcceptを設定してなかったのが原因.当然の結果だった.


test_controller_spec.rb

# 以下の行でAcceptを設定

before(:each) { request.env["HTTP_ACCEPT"] = 'application/json' }

describe 'GET #show' do
it 'returns valid response body' do
get :show, id: @test
expect(response.body).to # ...(略)
end
end



追記(2014/3/27)

上記の問題はController Specで発生するが,Request Specでは発生しないみたい.


JSONが返ってこない(なぜか空っぽになってる編)


内容

よし!これでJSONが返ってくるぞ!

…と思いきやどうやってもテストに失敗する.

puts request.bodyしてみると

{}

レスポンスボディがからっぽになっている.

どうもJSONの中身がちゃんとレンダリングされてない.


原因・対策

これはJSONのレンダリングに使ってるjbuilderというgemが原因らしい.

spec_helper.rbに1行足して問題解決.


spec_helper.rb

RSpec.configure do |config|

# 以下の行を追加
config.render_views = true
end


追記(2014/3/27)

これも同様に,上記の問題はController Specで発生するが、Request Specでは発生しないみたい.


まだまだあるけどつづきはまた今度…


参考