使用 RSpec 测试自定义验证方法
Testing custom validation method with RSpec
我尝试测试检查活动时间重叠的验证方法。
共有三个工厂(其中两个继承自activity)。
工厂:
activities.rb
FactoryGirl.define do
factory :activity do
name 'Fit Girls'
description { Faker::Lorem.sentence(3, true, 4) }
active true
day_of_week 'Thusday'
start_on '12:00'
end_on '13:00'
pool_zone 'B'
max_people { Faker::Number.number(2) }
association :person, factory: :trainer
factory :first do
name 'Swim Cycle'
description 'Activity with water bicycles.'
active true
day_of_week 'Thusday'
start_on '11:30'
end_on '12:30'
end
factory :second do
name 'Aqua Crossfit'
description 'Water crossfit for evereyone.'
active true
day_of_week 'Thusday'
start_on '12:40'
end_on '13:40'
pool_zone 'C'
max_people '30'
end
end
end
在相同 day_of_week(activity.day_of_week == first.day_of_week)、相同 pool_zone(activity.pool_zone == first.pool_zone) 和时间重叠。
验证方法:
def not_overlapping_activity
overlapping_activity = Activity.where(day_of_week: day_of_week)
.where(pool_zone: pool_zone)
activities = Activity.where(id: id)
if activities.blank?
overlapping_activity.each do |oa|
if (start_on...end_on).overlaps?(oa.start_on...oa.end_on)
errors.add(:base, "In this time and pool_zone is another activity.")
end
end
else
overlapping_activity.where('id != :id', id: id).each do |oa|
if (start_on...end_on).overlaps?(oa.start_on...oa.end_on)
errors.add(:base, "In this time and pool_zone is another activity.")
end
end
end
end
我写了rspec测试,不幸的是检查无效。
describe Activity, 'methods' do
subject { Activity }
describe '#not_overlapping_activity' do
let(:activity) { create(:activity) }
let(:first) { create(:first) }
it 'should have a valid factory' do
expect(create(:activity).errors).to be_empty
end
it 'should have a valid factory' do
expect(create(:first).errors).to be_empty
end
context 'when day_of_week, pool_zone are same and times overlap' do
it 'raises an error that times overlap' do
expect(activity.valid?).to be_truthy
expect(first.valid?).to be_falsey
expect(first.errors[:base].size).to eq 1
end
end
end
end
Return:
Failure/Error: expect(first.valid?).to be_falsey
expected: falsey value
got: true
我不明白为什么它是真的。 first create(:activity) 应该是正确的,但next不应该被执行(重叠)。
我尝试在 expect(first.valid?...
之前添加 expect(activity.valid?).to be truthy
,但抛出另一个错误 ActiveRecord::RecordInvalid
。有人可以修复我的测试吗?我是使用 RSpec.
创建测试的新手
更新:
我的问题的解决方案不是 create :first in test 而是 build。
let(:first) { build(:first) }
这一行独立
let(:activity) { create(:activity) }
不会创建 activity。它仅在实际调用 activity
时创建一个 activity。因此,您必须在 运行 测试之前的某处调用 activity
。
有几种方法可以做到这一点,例如前块:
before { activity }
或者您可以使用 let!
而不是 let
.
我尝试测试检查活动时间重叠的验证方法。
共有三个工厂(其中两个继承自activity)。
工厂:
activities.rb
FactoryGirl.define do
factory :activity do
name 'Fit Girls'
description { Faker::Lorem.sentence(3, true, 4) }
active true
day_of_week 'Thusday'
start_on '12:00'
end_on '13:00'
pool_zone 'B'
max_people { Faker::Number.number(2) }
association :person, factory: :trainer
factory :first do
name 'Swim Cycle'
description 'Activity with water bicycles.'
active true
day_of_week 'Thusday'
start_on '11:30'
end_on '12:30'
end
factory :second do
name 'Aqua Crossfit'
description 'Water crossfit for evereyone.'
active true
day_of_week 'Thusday'
start_on '12:40'
end_on '13:40'
pool_zone 'C'
max_people '30'
end
end
end
在相同 day_of_week(activity.day_of_week == first.day_of_week)、相同 pool_zone(activity.pool_zone == first.pool_zone) 和时间重叠。
验证方法:
def not_overlapping_activity
overlapping_activity = Activity.where(day_of_week: day_of_week)
.where(pool_zone: pool_zone)
activities = Activity.where(id: id)
if activities.blank?
overlapping_activity.each do |oa|
if (start_on...end_on).overlaps?(oa.start_on...oa.end_on)
errors.add(:base, "In this time and pool_zone is another activity.")
end
end
else
overlapping_activity.where('id != :id', id: id).each do |oa|
if (start_on...end_on).overlaps?(oa.start_on...oa.end_on)
errors.add(:base, "In this time and pool_zone is another activity.")
end
end
end
end
我写了rspec测试,不幸的是检查无效。
describe Activity, 'methods' do
subject { Activity }
describe '#not_overlapping_activity' do
let(:activity) { create(:activity) }
let(:first) { create(:first) }
it 'should have a valid factory' do
expect(create(:activity).errors).to be_empty
end
it 'should have a valid factory' do
expect(create(:first).errors).to be_empty
end
context 'when day_of_week, pool_zone are same and times overlap' do
it 'raises an error that times overlap' do
expect(activity.valid?).to be_truthy
expect(first.valid?).to be_falsey
expect(first.errors[:base].size).to eq 1
end
end
end
end
Return:
Failure/Error: expect(first.valid?).to be_falsey
expected: falsey value
got: true
我不明白为什么它是真的。 first create(:activity) 应该是正确的,但next不应该被执行(重叠)。
我尝试在 expect(first.valid?...
之前添加 expect(activity.valid?).to be truthy
,但抛出另一个错误 ActiveRecord::RecordInvalid
。有人可以修复我的测试吗?我是使用 RSpec.
更新:
我的问题的解决方案不是 create :first in test 而是 build。
let(:first) { build(:first) }
这一行独立
let(:activity) { create(:activity) }
不会创建 activity。它仅在实际调用 activity
时创建一个 activity。因此,您必须在 运行 测试之前的某处调用 activity
。
有几种方法可以做到这一点,例如前块:
before { activity }
或者您可以使用 let!
而不是 let
.