RailsApp Rails FactoryBot RSpec 2018年 11月 23日
昨日生成した kurasu_spec をクラスに合わせて設定する.
FactoryBot.define do
factory :kurasu do
end
end
##### ↑ write to spec/support/create_factories/kurasu_factory.rb
KurasuFactoryHash = {
hkob2300: %w[hkob 2300 f],
hkob5300o: %w[hkob 5300 t],
taro3300: %w[taro 3300 f]
}
# @param [Symbol, String] key オブジェクトを一意に決定するキー
# @return [Kurasu] Kurasu FactoryGirl オブジェクト
def kurasu_factory(key)
t, n, o = KurasuFactoryHash[key.to_sym]
FactoryBot.find_or_create(
:kurasu,
teacher_id: teacher_factory(t.to_sym).id,
name: n,
obsolete: o == 't',
) if t
end
# @param [Array<Symbol, String>] keys オブジェクトを一意に決定するキーの配列
# @return [Array<Kurasu>] Kurasu FactoryGirl オブジェクトの配列
def kurasu_factories(keys)
keys.map { |k| kurasu_factory(k) }
end
require 'rails_helper'
RSpec.describe Kurasu, type: :model do
context 'common validation check' do
subject { kurasu_factory :hkob2300 }
# name, obsolete, teacher_id 属性が nil の場合に validate に失敗することを確認(presence validation)
it_behaves_like :presence_validates, %i[name obsolete teacher_id]
#it_behaves_like :unique_validates, %i[], -> { kurasu_factory :other }
# name, teacher_id の組み合わせたが重複している場合に validate に失敗することを確認 (plural unique validation)
it_behaves_like :plural_unique_validates, %i[name teacher_id], -> { kurasu_factory :taro3300 }
# モデルオブジェクトが削除できるかを確認 (destroy validation)
it_behaves_like :destroy_validates
#it_behaves_like :reject_destroy_validates
# teacher への belong_to が正しく動作するか,また削除した時に teacher.kurasus が一つ減るかを確認
it_behaves_like :belongs_to, :kurasu, has_many: %i[teacher]
# teacher を削除した時に,連動して kurasu が削除されるかを確認
it_behaves_like :dependent_destroy, :kurasu, %i[teacher]
#it_behaves_like :reject_destroy_for_relations, :kurasu, %i[has_many has_one]
#it_behaves_like :destroy_nullify_for_relations, :kurasu, %i[has_many has_one]
end
context 'after some kurasus are registrered' do
model_keys = %i[hkob2300 hkob5300o taro3300]
let!(:targets) { kurasu_factories model_keys }
describe 'Kurasu class' do
subject { Kurasu }
# order_name の scope の確認
it_behaves_like :mst_block, -> t do
{
# 名前の順でソートできるか
order_name: [nil, t.values_at(0, 2, 1)],
}
end
# not_obsolete, teacher_is の scope の確認
it_behaves_like :msta_block, -> t do
{
# 有効なものだけ取得できるか
not_obsolete: [nil, t.values_at(0, 2)],
# teacher が hkob のものだけ取得できるか
teacher_is: [t.first.teacher, t.values_at(0, 1)],
}
end
#it_behaves_like :mst, :METHOD1, -> { [v1, kurasu_factories(model_keys.values_at()), v2, kurasu_factories(model_keys.values_at())] }
#it_behaves_like :msta, :METHOD1, -> { [v1, kurasu_factories(model_keys.values_at()), v2, kurasu_factories(model_keys.values_at())] }
end
context 'Kurasu instances' do
subject { targets }
# name の確認
it_behaves_like :amst_block, -> t do
{
name: [nil, %w[2300 5300 3300]],
}
end
#it_behaves_like :amsta_block, -> t do
# {
# method1: [v1, a1, v2, a2, ...],
# method2: [v1, a1, v2, a2, ...],
# }
#end
#it_behaves_like :amst, :METHOD1, -> { [v1, a1, v2, a2] }
#it_behaves_like :amsta, :METHOD1, -> { [v1, a1, v2, a2] }
end
end
end
Kurasu
common validation check
behaves like presence_validates
should be valid
when name is nil
should not be valid (FAILED - 1)
when obsolete is nil
should not be valid (FAILED - 2)
when teacher_id is nil
should not be valid (FAILED - 3)
behaves like plural_unique_validates
when another object has same name, teacher_id
should not be valid (FAILED - 4)
when another object has at least one different keys(name, teacher_id)
should be valid
behaves like destroy_validates
should destroy
should change `Kurasu.count` by -1
behaves like belongs_to
when destroying kurasu
teacher.kurasus.count should decrease (FAILED - 5)
behaves like dependent_destroy
when destroying teacher
should be destroyed by dependency (FAILED - 6)
after some kurasus are registrered
Kurasu class
behaves like mst_block
mst: order_name
should receive above methods(mst) (FAILED - 7)
behaves like msta_block
should receive above methods(msta) (FAILED - 8)
Kurasu instances
behaves like amst_block
amst: name
should receive above methods(amst)
kurasu_spec のテストが通過するように app/models/kurasu.rb に実装を記述する.
validates :name, :teacher_id, presence: {message: 'は空にはできません'}
validates :obsolete, inclusion: {in: [true, false], message: 'は空にはできません'}
validates :name, uniqueness: {scope: :teacher_id, message: '教員とクラスの組はユニークである必要があります.'}
# @return [Teacher] 関連する教員
belongs_to :teacher
# @return [Array<Kurasu>] 関連するクラス一覧
has_many :kurasus, dependent: :destroy
scope :order_name, -> { order :name }
scope :not_obsolete, -> { where obsolete: false }
scope :teacher_is, -> t { where teacher_id: t.id }
Kurasu
common validation check
behaves like presence_validates
should be valid
when name is nil
should not be valid
when obsolete is nil
should not be valid
when teacher_id is nil
should not be valid
behaves like plural_unique_validates
when another object has same name, teacher_id
should not be valid
when another object has at least one different keys(name, teacher_id)
should be valid
behaves like destroy_validates
should destroy
should change `Kurasu.count` by -1
behaves like belongs_to
when destroying kurasu
teacher.kurasus.count should decrease
behaves like dependent_destroy
when destroying teacher
should be destroyed by dependency
after some kurasus are registrered
Kurasu class
behaves like mst_block
mst: order_name
should receive above methods(mst)
behaves like msta_block
msta: not_obsolete
msta: teacher_is
should receive above methods(msta)
Kurasu instances
behaves like amst_block
amst: name
should receive above methods(amst)
Finished in 0.31014 seconds (files took 0.39904 seconds to load)
12 examples, 0 failures
長くなったので今日はここまで