Rails – 枚举字段的测试validation

我正在使用Rails 4枚举,我想正确测试它们,所以我为枚举字段设置了这些测试:

it { should validate_inclusion_of(:category).in_array(%w[sale sale_with_tax fees lease tax_free other payroll]) } it { should validate_inclusion_of(:type).in_array(%w[receivable payable]) } 

这是他们正在validation的模型:

 class Invoice < ActiveRecord::Base belongs_to :user enum category: [:sale, :sale_with_tax, :fees, :lease, :tax_free, :other, :payroll] enum type: [:receivable, :payable] validates :user, presence: true validates :issue_date, presence: true validates :series, presence: true validates :folio, presence: true validates :issuing_location, presence: true validates :payment_method, presence: true validates :last_digits, presence: true validates :credit_note, presence: true validates :total, presence: true validates :subtotal, presence: true validates :category, presence: true validates_inclusion_of :category, in: Invoice.categories.keys validates :type, presence: true validates_inclusion_of :type, in: Invoice.types.keys end 

但是当我运行测试时,我得到:

 1) Invoice should ensure inclusion of type in [0, 1] Failure/Error: it { should validate_inclusion_of(:type).in_array([0,1]) } ArgumentError: '123456789' is not a valid type # ./spec/models/invoice_spec.rb:20:in `block (2 levels) in ' 2) Invoice should ensure inclusion of category in [0, 1, 2, 3, 4, 5, 6] Failure/Error: it { should validate_inclusion_of(:category).in_array([0,1,2,3,4,5,6]) } ArgumentError: '123456789' is not a valid category # ./spec/models/invoice_spec.rb:19:in `block (2 levels) in ' 

我也试过测试数组中的字符串值,但是我得到了同样的错误,我真的不理解它。

使用Shoulda匹配器,我们可以使用以下内容来测试枚举

 it { should define_enum_for(:type).with([:receivable, :payable]) } it { should define_enum_for(:category). with(:sale, :sale_with_tax, :fees, :lease, :tax_free, :other, :payroll) } 

试试这个:

it { should validate_inclusion_of(:category).in_array(%w[sale sale_with_tax fees lease tax_free other payroll].map(&:to_sym)) }

此外,对于代码清理,请尝试将有效的类别/类型放在相应的常量中。 例:

 class Invoice < ActiveRecord::Base INVOICE_CATEGORIES = [:sale, :sale_with_tax, :fees, :lease, :tax_free, :other, :payroll] enum category: INVOICE_CATEGORIES end 

您的迁移可能是问题,它应该类似于:

t.integer :type, default: 1

您也可以考虑以另一种方式进行测试。

也许更喜欢:

 it "validates the category" do expect(invoice with category fee).to be_valid end 

您的validation中包含此字符串:

 validates_inclusion_of :category, in: Invoice.categories.keys 

如果是enum Invoice.categories.keys#=> [“sale”,“sale_with_tax”,“费用”,“租约”,“tax_free”,“其他”,“工资单”]

您应该使用枚举名称之一更新对象数据。