FactoryGirl在使用包含必需属性的特征创建时未通过验证



我有一个用户模型,它有两个角色:memberadmin,默认为member。此模型具有两个必需的属性payout_bankpayout_account,并且仅当角色为member时才要求它们存在。

我的FactoryGirl用户有两个与角色相对应的特征。然后,我将两个必需的属性添加到member特性中,但当我创建一个成员特性为"linting"且FactoryGirl处于打开状态的用户时,我会抱怨必需的属性未通过验证,因为它们是空白的。

如果我关闭linting,它将正确生成填写了payout_bankpayout_account的成员User。怎么回事?

模型用户.rb

class User < ActiveRecord::Base
  validates_presence_of :payout_bank, :payout_account, if: :member?
  def set_default_role
    self.role ||= :member
  end
end

工厂用户.rb

FactoryGirl.define do
  factory :user do
    sequence(:email) { |n| "user#{n}@email.com" }
    password "password"
    trait :member do
      sequence(:email) { |n| "member#{n}@email.com" }
      role "member"
      payout_bank { Faker::Company.name }
      payout_account { Faker::Number.number(10) }
    end
    trait :admin do
      sequence(:email) { |n| "admin#{n}@email.com" }
      role "admin"
      status "active"
    end
  end
end

从工厂创建用户

FactoryGirl.lint
FactoryGirl.create(:member_user, :member)

输出

FactoryGirl::InvalidFactoryError: The following factories are invalid:
* member_user - Validation Failed: payout_bank cannot be blank, payout_account cannot be blank (ActiveRecord::RecordInvalid)/usr/local/lib/ruby/gems/2.3.0/gems/factory_girl-4.7.0/lib/factory_girl/linter.rb:12:in `lint!'

您必须在规范/模型目录中编写验证测试。有点像。

需要"rails_helper"需要"validates_email_format_of/rspec_matcher"

RSpec.describe BankAccount, type: :model do
  it "should have a account number" do
    bank_a = build(:bank_account, account_no: '')
    expect(bank_a).to_not be_valid
  end
end

我发现FactoryGirl.lint是导致验证失败的线路。这里的问题是linting将尝试创建没有特征的通用用户模型。由于我的用户模型默认为member角色,并且该角色需要payout_bankpayout_account在场,因此验证失败。

解决方案是将这两个属性从member特性移到工厂的基础中。

像这样的

FactoryGirl.define do
  factory :user do
    sequence(:email) { |n| "user#{n}@email.com" }
    password "password"
    payout_bank { Faker::Company.name } # Move here
    payout_account { Faker::Number.number(10) } # Move here
    trait :member do
      sequence(:email) { |n| "member#{n}@email.com" }
      role "member"
    end
    trait :admin do
      sequence(:email) { |n| "admin#{n}@email.com" }
      role "admin"
      status "active"
      payout_bank nil
      payout_account nil
    end
  end
end

最新更新