RspecでModelに定義したScopeのテストを書いてみる
こんにちは!kossyです!
さて、今回は、冗長なDB検索ロジックに名前をつけてひとまとめにできる機能であるscopeのテストを
Rspecで書いてみたいと思います。
scopeの定義
class Article < ApplicationRecord scope :open_to_the_public, -> { where(member_only: false) } scope :visible, -> do now = Time.now where('released_at <= ?', now).where('expired_at > ? OR expired_at IS NULL' , now) end end
Articleというモデルに2つscopeを定義しています。
ModelsSpec
テストケースはこんな感じです。
require 'rails_helper' RSpec.describe 'ArticleScope', type: :model do let!(:article_1) { create :article, member_only: true } let!(:article_2) { create :article, member_only: true } let!(:article_3) { create :article, expired_at: Date.today, member_only: false } describe ':open_to_the_public' do it 'member_onlyがfalseの記事が検索される' do expect(Article.open_to_the_public).to include(article_3) end it 'member_onlyがtrueの記事は検索されない' do expect(Article.open_to_the_public).to_not include(article_1, article_2) end end describe ':visible' do it '(released_at <= ?, now)かつ(expired_at > ? OR expired_at IS NULL , now)の記事が検索される' do expect(Article.visible).to include(article_1, article_2) end it '(released_at <= ?, now)かつ(expired_at > ? OR expired_at IS NULL , now)でない記事は検索されない' do expect(Article.visible).to_not include(article_3) end end end
あらかじめ条件に合致するものとしないものをモックにしておき、
scopeを実行して想定通りのレコードを抽出してくるかをチェックしています。
こんなんでいいんじゃないでしょうか。(適当)