Overview
この記事では、factory_bot_rails
Gem(FactoryBot)を使ってテストデータを作成し、テストを作成・実行するまでの方法を書いてみようと思います。
Motivation/context
EverydayRspecの本を読んで、自分で作ってるアプリにfactoyBotを追加してみました。
何度も実行しそうなコマンドや内容なのでここにメモしておきます。
今回はFaq
モデルに対するfactoryBotとRspecを追加していきます。
Faqモデルは「よくあるご質問」に関するモデルですので、タイトル(title)と内容(content)というシンプルな2カラム構成です。
Get Started!!
Faqモデルスペックの作成
rails g rspec:model faq
Faqのファクトリーファイル作成
rails generate factory_bot:model Faq
テストケースを書いてみる
ポイント
- 普通であればitであるところをfitとしているのは、新規で追加したテストだけを
$bundle exec rspec
実行時に実行したいからです。(commit前にfitはitに変換されます)
spec/models/faq_spec.rb
require 'rails_helper'
RSpec.describe Faq, type: :model do
fit "title,contextがあれば有効名こと" do
faq = FactoryBot.build(:faq)
expect(faq).to be_valid
end
describe "存在性" do
context "titleがない場合" do
fit "エラーになる" do
faq = FactoryBot.build(:faq, title: nil)
faq.valid?
expect(faq.errors[:title]).to include("を入力してください")
end
end
context "contentがない場合" do
fit "エラーになる" do
faq = FactoryBot.build(:faq, content: nil)
faq.valid?
expect(faq.errors[:content]).to include("を入力してください")
end
end
end
describe "文字数の境界値" do
context "titleが1文字だけの場合" do
fit "無効である" do
faq = FactoryBot.build(:faq, title: "a")
faq.valid?
expect(faq.errors[:title]).to include("は2文字以上で入力してください")
end
end
context "titleが2文字だけの場合" do
fit "有効である" do
faq = FactoryBot.build(:faq, title: "a" * 2)
expect(faq).to be_valid
end
end
context "titleが30文字の場合" do
fit "有効である" do
faq = FactoryBot.build(:faq, title: "a" * 30)
expect(faq).to be_valid
end
end
context "titleが31文字の場合" do
fit "有効である" do
faq = FactoryBot.build(:faq, title: "a" * 31)
faq.valid?
expect(faq.errors[:title]).to include("は30文字以内で入力してください")
end
end
end
end
FactoryBotでテストデータを作成
spec/factories/faqs.rb
FactoryBot.define do
factory :faq do
title { "Sample" }
content { "..." }
end
end
Faqモデルを編集
class Faq < ApplicationRecord
validates :title, presence: true, length: { in: 2...31 }
validates :content, presence: true
end
Rspecの実行
it
をfit
に変更していたことにより、このコマンドでも新規追加分のテストだけを実行してくれる。
いちいち全部のテストケースを流す必要はないですからね!!
$ bundle exec rspec
終わった後に気づいたこと
テストの構造なのですが... context
の中にitが1つだけなんて、なんか悲しいので、こういう感じにすればよかったと後悔!!
- context "titleが1文字だけの場合" do
- context "titleの入力値が足りない場合" do
こうすれば、contextの数が少なくなって、条件を一まとめにできた・・・。