21
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2014-03-27

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


RailsのController TestでWeb APIのテストをするときにハマったシリーズその②.

その①はこちら(【Rails】RSpecでWeb APIのテストでハマったところ①).

ハマったところ

そもそもどうやって中身をテストしようか…

Everyday Rails - RSpecによるRailsテスト入門』訳者の@jnchitoさんがすばらしいgemを教えて下さいました.

ということでjson_specを使っていこうとしたのですが,超クセが強くていっぱいハマりました.

json_specで文字列の比較ができない

内容

Lectureというmodelの指定したid要素を取ってくるLecturesController#showのレスポンスのテストしようと以下のようなspecを記述.

spec/requests/lectures_spec.rb
describe 'GET /api/v1/lectures/:id' do
  let(:lecture) { FactoryGirl.create(:lecture) }
  before(:each) { get :show, lecture: lecture }

  it 'returns lecture json' do
    expect(response.body).to have_json_path('lecture')
    expect(response.body).to be_json_eql(lecture.id).at_path('lecture/id')
    expect(response.body).to be_json_eql(lecture.title).at_path('lecture/title')
  end
end

期待してるレスポンスはこんな感じ.

{
  "lecture": {
    "id": 1,
    "title": "プログラミングI"
  }
}

しかしエラーが出る(MultiJson::ParseError).

Failures:

  1. Lectures GET /lectures/:id returns lecture json
    Failure/Error: expect(response.body).to be_json_eql(lecture.title).at_path('lecture/title')
    MultiJson::ParseError:
    795: unexpected token at ...(略)

原因・対策

be_json_eqlにそのまま文字列を渡したらダメっぽい?
こんな感じでダブルクォートをつけてあげないといけない.

spec/requests/lectures_spec.rb
expect("\"#{response.body}\"").to be_json_eql(lecture.title).at_path('lecture/title')

FactoryGirlがツンデレ

内容

よくわからんけどFactoryGirl.create()でnilが返ってきてた.しかしエラーは出ていない.何故.

(lecture has many timetablesです)

spec/factories/lectures.rb
FactoryGirl.define do
  factory :lecture do
    title { Faker::Lorem.word }
    after(:build) do |lecture, evaluator|
      create_list(:timetable, evaluator.timetables_count, lecture: lecture)
    end
  end
end

原因・対策

なにをしても改善されないので試しにdatabase_cleanerを導入してみる.

spec_helper.rb
config.before(:suite) do
  begin
    DatabaseCleaner.start
  ensure
    DatabaseCleaner.clean
  end
end

何故かテストがとおった

考察

lecturehas_manyになってるtimetableのfactoryがバリデーションに引っかかって落ちてたような気がする.
テスト用DBがうまいこと初期化されてなくてそんなことになってたのかなーと考察.


ちょっと適当にだらだら書いてしまっただけになってるので,「RSpecで書くWeb APIのテストまとめ」みたいな記事が必要かもしれない(自分のためにも).

参考

21
21
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?