FactoryGirl + Rspec 自定义验证测试
FactoryGirl + Rspec custom validation test
我对测试还很陌生。
我在个人资料模型中进行了自定义验证
def birth_date_cannot_be_in_the_future
errors.add(:birth_date, "the birth date cannot be in the future") if
!birth_date.blank? && birth_date > Date.today
end
在我的factories.rb
sequence(:email) {|n| "person-#{n}@example.com"}
factory :user do
email
password 'password'
password_confirmation 'password'
confirmed_at Time.now
end
factory :profile do
user
first_name { "User" }
last_name { "Tester" }
birth_date { 21.years.ago }
end
在我的 models/profile_spec.rb
it 'birth date cannot be in the future' do
profile = FactoryGirl.create(:profile, birth_date: 100.days.from_now)
expect(profile.errors[:birth_date]).to include("the birth date cannot be in the future")
expect(profile.valid?).to be_falsy
end
当我 运行 我的测试时,我收到以下消息:
Failure/Error: profile = FactoryGirl.create(:profile, birth_date: 100.days.from_now)
ActiveRecord::RecordInvalid:
The validation fails: Birth date the birth date cannot be in the future
我做错了什么?
有一个匹配器专门用于捕获错误。没有测试,我假设你可以去:
expect { FactoryGirl.create(:profile, birth_date: 100.days.from_now) }.to raise_error(ActiveRecord::RecordInvalid)
另一种方法是包含 shoulda
gem,它具有 allow_value
匹配器。这使您可以在模型规范中做更多类似的事情:
describe Profile, type: :model do
describe 'Birth date validations' do
it { should allow_value(100.years.ago).for(:birth_date) }
it { should_not allow_value(100.days.from_now).for(:birth_date) }
end
end
通常,当您测试诸如验证之类的东西时,您根本不需要 FactoryGirl。不过,它们在控制器测试中变得非常有用。
只需将模型的断言放在模型规范中,它会直接测试您的模型代码。这些通常存在于 spec/models/model_name_spec.rb
有一些方便的 shoulda 匹配器用于一堆常见的模型东西:
describe SomeModel, type: :model do
it { should belong_to(:user) }
it { should have_many(:things).dependent(:destroy) }
it { should validate_presence_of(:type) }
it { should validate_length_of(:name).is_at_most(256) }
it { should validate_uniqueness_of(:code).allow_nil }
end
应该使用 build
而不是 create
另外 profile.valid?
应该在检查 profile.errors
之前调用
it 'birth date cannot be in the future' do
profile = FactoryGirl.build(:profile, birth_date: 100.days.from_now)
expect(profile.valid?).to be_falsy
expect(profile.errors[:birth_date]).to include("the birth date cannot be in the future")
end
我对测试还很陌生。
我在个人资料模型中进行了自定义验证
def birth_date_cannot_be_in_the_future
errors.add(:birth_date, "the birth date cannot be in the future") if
!birth_date.blank? && birth_date > Date.today
end
在我的factories.rb
sequence(:email) {|n| "person-#{n}@example.com"}
factory :user do
email
password 'password'
password_confirmation 'password'
confirmed_at Time.now
end
factory :profile do
user
first_name { "User" }
last_name { "Tester" }
birth_date { 21.years.ago }
end
在我的 models/profile_spec.rb
it 'birth date cannot be in the future' do
profile = FactoryGirl.create(:profile, birth_date: 100.days.from_now)
expect(profile.errors[:birth_date]).to include("the birth date cannot be in the future")
expect(profile.valid?).to be_falsy
end
当我 运行 我的测试时,我收到以下消息:
Failure/Error: profile = FactoryGirl.create(:profile, birth_date: 100.days.from_now)
ActiveRecord::RecordInvalid:
The validation fails: Birth date the birth date cannot be in the future
我做错了什么?
有一个匹配器专门用于捕获错误。没有测试,我假设你可以去:
expect { FactoryGirl.create(:profile, birth_date: 100.days.from_now) }.to raise_error(ActiveRecord::RecordInvalid)
另一种方法是包含 shoulda
gem,它具有 allow_value
匹配器。这使您可以在模型规范中做更多类似的事情:
describe Profile, type: :model do
describe 'Birth date validations' do
it { should allow_value(100.years.ago).for(:birth_date) }
it { should_not allow_value(100.days.from_now).for(:birth_date) }
end
end
通常,当您测试诸如验证之类的东西时,您根本不需要 FactoryGirl。不过,它们在控制器测试中变得非常有用。
只需将模型的断言放在模型规范中,它会直接测试您的模型代码。这些通常存在于 spec/models/model_name_spec.rb
有一些方便的 shoulda 匹配器用于一堆常见的模型东西:
describe SomeModel, type: :model do
it { should belong_to(:user) }
it { should have_many(:things).dependent(:destroy) }
it { should validate_presence_of(:type) }
it { should validate_length_of(:name).is_at_most(256) }
it { should validate_uniqueness_of(:code).allow_nil }
end
应该使用 build
而不是 create
另外 profile.valid?
应该在检查 profile.errors
it 'birth date cannot be in the future' do
profile = FactoryGirl.build(:profile, birth_date: 100.days.from_now)
expect(profile.valid?).to be_falsy
expect(profile.errors[:birth_date]).to include("the birth date cannot be in the future")
end