简体   繁体   English

FactoryGirl + Rspec自定义验证测试

[英]FactoryGirl + Rspec custom validation test

I'm pretty new to testing. 我是测试的新手。

I have a custom validation at my Profile model 我的个人资料模型上有一个自定义验证

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

At my factories.rb 在我的factory.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

At my models/profile_spec.rb 在我的模型/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

When I run my test I receive the follow message: 运行测试时,我收到以下消息:

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

What am I doing wrong? 我究竟做错了什么?

There's a matcher just for catching errors. 有一个匹配器仅用于捕获错误。 Without having tested, I'm assuming you can go: 未经测试,我假设您可以:

expect { FactoryGirl.create(:profile, birth_date: 100.days.from_now) }.to raise_error(ActiveRecord::RecordInvalid)

Another approach though is to include the shoulda gem, which has the allow_value matcher. 另一种方法虽然是包括shoulda宝石,它具有allow_value匹配。 This lets you do something more like this in your model spec: 这使您可以在模型规格中执行以下操作:

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

Generally you wont need FactoryGirl at all when you're testing things like validations. 通常,在测试诸如验证之类的东西时,您根本不需要FactoryGirl。 They become super useful in controller tests though. 它们在控制器测试中变得超级有用。

Just put assertions for your model in a model spec, which tests your model code directly. 只需将模型的断言放在模型规范中,即可直接测试模型代码。 These usually live in spec/models/model_name_spec.rb There are convenient shoulda matchers for a bunch of common model stuff: 这些通常存在于spec/models/model_name_spec.rb中。一堆常见的模型匹配项应该有一些便利的matcha匹配器:

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

It should be using build instead of create 它应该使用build而不是create

Also profile.valid? 也是profile.valid? should be called before checking profile.errors 应该在检查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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM