FactoryGirl + Rspec自定义验证测试

时间:2016-11-03 01:06:43

标签: ruby-on-rails rspec factory-bot

我对测试很陌生。

我在个人资料模型中进行了自定义验证

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

我做错了什么?

2 个答案:

答案 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