Model Spec
概要
taskモデルのバリデーションに関するテストを作成する。
FactoryBotを使用しテストデータを作成する。
バリデーションエラーの発生と、エラーメッセージの内容を表示させる。
各バリデーションを削除した際、テストが失敗することを確認する。
FactoryBotの設定
FactoryBot.
の省略
以下の設定を追加すると、factory_botメソッドの前にFactoryBot.
を付ける必要がなくなる。FactoryBot.create(:user)
→create(:user)
と省略して書ける。
RSpec.configure do |config| config.include FactoryBot::Syntax::Methods end
UserとTaskモデルのテストデータを作成
FactoryBot.define do factory :task do sequence(:title, "title_1") content { 'Content' } status { 'todo' } deadline { Date.current.tomorrow } association :user end end
FactoryBot.define do factory :user do sequence(:email) { |n| "tester#{n}@example.com" } password { 'password' } password_confirmation { 'password' } end end
今回のUserとTaskのアソシエーションは1対多(belongs_to と has_many)である。
ユニーク制約のついているカラムではsequence
メソッドを使用する。
association :user
でuserとの関連を定義。
sequenceメソッド
sequenceの第二引数で定義した文字にはループの度に.next
が実行される。
> "title_1".next => "title_2"
sequence(:title){|n| "title_#{n}"}
→sequence(:title, "title_1")
のように書ける。
TaskのModel Spec
taskモデルのvalidationに関するテストを記述していく。
- 全部の属性を登録したとき有効
- titleがないときに無効
- titleが重複したとき無効
require 'rails_helper' RSpec.describe Task, type: :model do describe 'validation' do it "is valid with all attributes" do task = build(:task) expect(task).to be_valid expect(task.errors).to be_empty end it "is invalid without a title" do task_without_title = build(:task, title: "") expect(task_without_title).to be_invalid expect(task_without_title.errors[:title]).to eq ["can't be blank"] end it "is invalid with a duplicate title" do task = create(:task) task_with_duplicated_title = build(:task, title: task.title) expect(task_with_duplicated_title).to be_invalid expect(task_with_duplicated_title.errors[:title]).to eq ["has already been taken"] end end end
describe' 'do...end
でテスト内容の宣言。
今回はvalidationに関するテストを宣言している。
it " " do...end
には、実行するテスト内容を記述する。
be_○○○マッチャ
Rspecでは、empty? のようにメソッド名が?で終わり、戻り値が true / false になるメソッドを be_empty のような形式で検証できる。
expect(task).to be_valid
で記述するのがexpect(期待する)で、ここでは
taskがto be_validすることを期待する
というテストとなる。
be_valid
はマッチャと呼ばれる機能でexpectの引数にしたインスタンスにバリデーションエラーが発生しないことを検証する。(task.valid? が true になればパスする)
expect(task.errors).to be_empty
でtask.errorsがemptyであることを期待する。
省略
task = FactoryBot.build(:task, title: "", user: user)
→task = build(:task)
と書ける。
FactoryBot.buildでTaskのFactoryにuserオブジェクトを指定。
設定ファイルへ追記しているので、FactoryBot.の部分は省略できる。
taskのFactoryにassociationを定義しているのでuserの記述を省略できる。
buildとcreateの違い
buildはテストデータをメモリ上に保存するが、createはデータベース上に保存する。
データベースへのアクセスが必要なテストの場合はcreateを使用し、必要でない場合はbuildを使えば良い
以下、idや作成日時を見るとbuildではnilとなっていて、createではデータベース上に保存されているので値が表示されている。