Open9

rails-rspecを記述した時の知見

RyosukeMochizukiRyosukeMochizuki

前提FactoryBotを使っている.

rails_helper.rb
RSpec.configure do |config|
  # create()やbuild()を使えるようにする(シンタックスシュガー)
  config.include FactoryBot::Syntax::Methods
end

Rails.logger = Logger.new(STDOUT) # Rails.loggerを出す
ActiveRecord::Base.logger = Logger.new(STDOUT) # SQLログ出す

上を埋め込んだ状態で以下をspecファイルに書くと中身が見れる

STDOUT.puts request.params
STDOUT.puts response.status
STDOUT.puts response.headers
STDOUT.puts response.body
......などなど
RyosukeMochizukiRyosukeMochizuki
rails_helper.rb
# rspec実行ごとにdbをリセットしてseedsを読み込む
RSpec.configure do |config|
  config.before(:suite) do
    DatabaseCleaner.strategy = :transaction
    DatabaseCleaner.clean_with(:truncation)
    load Rails.root.join('db', 'seeds.rb')
  end
end

→ここってどの順番が最適なのだろう

RyosukeMochizukiRyosukeMochizuki

例えば以下のように、直書きしてレコードを作成した時。
これを直接使いたい場合は、シンボルuser[:first_name]で扱える.
(ログでuserを出力するとわかる)

let!(:user) {{ id: 1, first_name: 'taro', last_name: 'yamada' }}
RyosukeMochizukiRyosukeMochizuki

以下のようにするとパラメータが送れるが、全てが文字列となって送られてしまう。
(ログに出力するとわかる)
全部文字列ならギリセーフだけど、integer, bigintだったりするとアウト。

let!(:user_params) {{ first_name: 'taro', last_name: 'yamada', age: 20 }}
post /v1/users, params: user_params

解決するには、下のようにする。

let!(:user_params) {{ first_name: 'taro', last_name: 'yamada', age: 20 }}
post /v1/users, params: user_params.to_json, headers: { 'Content-type' => 'application/json' }

これで記述した値のまま扱える。
(基本的に書いた方が良さそう)

RyosukeMochizukiRyosukeMochizuki

※以下は自分の感覚です。

  • indexメソッドとか(一覧返却とか)は、expect(~).to include '~'とかでプロパティ一致で判断した方が良さそう
  • post(新規作成)は、change(モデル名, :count).by(1)で数による判断をした方が良さそう
  • delete(削除)は、change(モデル名, :count).by(-1)で数による判断をした方が良さそう
  • (updateの余地あるが)以下のようなフォーマットでも良さそう
describe 'アクション名' do
  context 'HTTPメソッド名' do
    it '何が起こるか?' do
      ~~~
    end
  end
end
  • パスは、先にまとめておくとよい

seedでテストデータを入れないパターンと入れるパターン

  • 依存関係がないモデルのレコードはseedで入れておいて使う
  • 依存関係がある(外部キー制約とか)場合は、FactoryBotで作った方が扱いやすい
RyosukeMochizukiRyosukeMochizuki
  • リクエストをキャメルケースからスネークケースに変換する。(deep_snakeize)

https://qiita.com/vochicong/items/d64f3b3d5a448a3b1f42

  • レスポンスを返す時はActiveModelSerilaizerを使ってスネークケースをキャメルケースに変換する。

上記2つをやっておくと、お互いの言語仕様に囚われず開発が進められる。

RyosukeMochizukiRyosukeMochizuki

factory botの備忘

  • 値を指定しなければ設定しなくてもリクエストを送れる。
    (header認証等でcurrent_userを判別する場合は、paramsにuserIDを載せなくてもいい)
    ex) お問い合わせ
  factory :contact do
    user         ←こんな感じ
    contact_category {1}
    body { "本文" }
    email { "aaa@example.com" }
  end