我对测试很陌生。
我在个人资料模型中进行了自定义验证
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
在我的工厂.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
我做错了什么?
答案 0 :(得分:3)
有一个匹配器只是为了捕捉错误。没有经过测试,我假设你可以去:
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
中。对于一堆常见的模型,有一些方便的应用匹配器:
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
答案 1 :(得分:0)
它应该使用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