5
1

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.

【RSpec】modelのscope

Posted at

ごあいさつ & はじめに

本日より、株式会社OCEAN GATEのイッカツ開発チームの一員として、Qiitaにどんどん記事を投稿していきます!

今はまだプログラミング初心者ですが、業務で学んだことをアウトプットしていきます!
よろしくお願いします!

さて、本題に入ります。

modelにはscopeという、クエリをまとめられる書き方があります。
そのscopeのテストの書き方を学んだのでまとめていきます。

scopeのテスト

  • model
models/place.rb
scope :deleted, -> { where(is_deleted: true) }

上記のplace.rbdeletedに対し、次のようにSpecを書けます。

  • spec
spec/models/place.rb
describe 'scope' do
  describe 'deleted' do
    let!(:place) { create(:place) }       # --①
    subject { Place.is_deleted }          # --②
    it { is_expected.to include place }   # --③
  end
end

ここで何をしているかを説明していきます。
①では、FactoryBotを使ってplaceのデータを作成しています。

②では、modelに書かれているis_deletedscopeをPlaceモデルに使っています。
 そして、subjectとして設定しています。

③では、②のsubjectの配列が、①のデータの配列を含んでいることをテストしています。
 includeはマッチャです。

非常にスッキリとしています!

belongs_to のアソシエーションがある場合

belongs_toというアソシエーションがあるときのテストの書き方でかなり悩みました。

そのため、その内容も書いていきます。

  • model
models/ornament.rb
belongs_to :place
scope :place_ornaments, -> (place_id) { where(place_id: place_id) }

今回は、placeにひもづくornamentモデルを使っていきます。

  • spec
spec/models/ornament_spec.rb
describe 'place_ornaments' do
  let!(:place) { create(:place) }                      # --④
  let!(:ornament) { create(:ornament, place: place) }  # --⑤
  subject { Ornament.place_ornaments(place.id) }       # --⑥
  it { is_expected.to include ornament }
end

④では、FactoryBotを使ってplaceのデータを作成しています。
 そうしないと、ornamentが作れないためです。

⑤では、ornamentのデータ作成時に④のplaceを渡しています。
このplace:を使えるの?と思うかもしれません。

実は、FactoryBotで定義していれば使えるのです!

spec/factories/ornaments.rb
factory :ornament do
  place
end

ornamentはplace_idを持っているので、FactoryBotにはplaceが必要になります。

そのplaceに、④のplaceを渡しておけばbelongs_toのあるscopeのテストも実行できます。

scopeで変数を使っている場合

上記のplace_ornamentsでは、place_idが引数として渡されています。
そのため、引数を指定しないとこのscopeが使用できません。

そこで、⑥のように、place.idをscopeの後に渡してあげればscopeを使用できるようになります。

おわりに

このようにscopeのテストは意外と簡単に書けてしまいます!
テストはこわくない!

参考

RspecでModelに定義したScopeのテストを書いてみる

使えるRSpec入門・その2「使用頻度の高いマッチャを使いこなす」

5
1
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
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?