モデルスペック
導入
モデルスペックの作成
rails g rspec:model taskでタスクモデルを作成
FactoryBotの設定
emailとtitleはユニーク制約がついている
spec/factories/users.rb FactoryBot.define do factory :user do sequence(:email) { |n| "tester#{n}@example.com" } password { 'password' } password_confirmation { 'password' } end end
sequenceとは、連番データを作成できるもの
ユニークな値にすることができる
spec/factories/tasks.rb FactoryBot.define do factory :task do sequence(:title, "title_1") content { 'Content' } status { 'todo' } #enumで定数を設定している。 deadline { Date.current.tomorrow } association :user end end
sequence(:title, "title_1")の部分は、sequenceはブロックを渡さず第2引数を渡すと、.nextが呼ばれる。変えたい場所が末尾の場合のみ使える書き方 なのかなと思う
FactoryBotは、FactoryBot.create(略)のように記述するが、以下の設定をしておくと、FactoryBotを省略できる
spec/rails_helper.rb RSpec.configure do |config| config.include FactoryBot::Syntax::Methods #追記 end
テストコード記述
spec/models/task_spec.rb require 'rails_helper' RSpec.describe Task, type: :model do pending "add some examples to (or delete) #{__FILE__}" 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 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 without status' do task_without_status = build(:task, status: nil) expect(task_without_status).to be_invalid expect(task_without_status.errors[:status]).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 it 'is valid with another title' do task = create(:task) task_with_another_title = build(:task, title: 'another_title') expect(task_with_another_title).to be_valid expect(task_with_another_title.errors).to be_empty end end end
validとinvalid
valid
バリデーションが実行された結果 エラーが無い場合trueを返し,エラーが発生した場合falseを返す
invalid
validとは逆の結果を返す エラーが発生した場合true,エラーが無い場合falseを返す