0
0

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 3 years have passed since last update.

なんということでしょう、匠の手によりandメソッドが導入され、テストのexampleが減ったではありませんか

Last updated at Posted at 2021-04-19

formオブジェクトを用いてリクエストテスト、結合テストを行いリソースの保存を検証したい

class Output
  include ActiveModel::Model
  attr_accessor :content, :user_id, :book_id, :awareness, :action_plans

  def save
    awareness = Awareness.new(content: content, book_id: book_id, user_id: user_id)
    awareness.save
    action_plans.each do |action_plan|
      action_plan = ActionPlan.new(time_of_execution: action_plan[:time_of_execution], what_to_do: action_plan[:what_to_do], how_to_do: action_plan[:how_to_do], book_id: book_id, user_id: user_id, awareness_id: awareness.id)
      action_plan.save
      BookActionPlan.create(book_id: book_id, action_plan_id: action_plan.id)
    end
  end
end

こんな感じで一度に複数のモデルにデータを挿入するformオブジェクトを生成した。
本を読んだ気づきとアクションプラン(1~3個で変動)を同時に保存することができる。
これを用いてリクエストテストやユニットテストを実装する際にリソースの保存処理の書き方で困った

changeマッチャを使ってモデルのカウントの上昇分を検証する

普通rspecでリソースの保存を検証する際には

expect do 
  post hoge_path
end.to change(Hoge, :count).by(1)

のようにやる。こうすることでモデルのカウントが増えていることを検証している。

ところが今回のformオブジェクトでは検証すべきモデルが複数あるのでこういうときはどう書くのか?というのがわからなかった。

exampleを複数用意することでも対処は可能だけど

it "投稿に成功するとAwarenessモデルのカウントが1増える" do
  expect do
    post api_v1_book_outputs_path(book.id), xhr: true, params: {output: output_params}, headers: headers
    sleep 2
  end.to change(Awareness, :count).by(1)
end


it "投稿に成功するとActionPlanモデルのカウントが3増える" do
  expect do
    post api_v1_book_outputs_path(book.id), xhr: true, params: {output: output_params}, headers: headers
    sleep 2
  end.to change(ActionPlan, :count).by(3)
end

こんな感じでexampleを複数はやしてもいいんだけどなんか冗長だなぁと感じていた。
すると以下の記事にヒットした。

andメソッドを使うことで検証内容を増やす

it "投稿に成功するとAwarenessモデルのカウントが1増え、ActionPlanモデルのカウントが3増える" do
  expect do
    post api_v1_book_outputs_path(book.id), xhr: true, params: {output: output_params}, headers: headers
    sleep 2
  end.to change(Awareness, :count).by(1).and change(ActionPlan, :count).by(3)
end

こんな感じでandでつなげることでcountの検証を複数同時に行うことができる。
すげぇこんなのあるのか…
私はこれを知った時稲妻が落ちたような気持ちになった。

実際のアプリの環境に照らしても同時に検証できる方がベターなのでこれでコードの可読性もテストとしての安全性も高まった。やったね!

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?