ruby-on-rails Rails -测试枚举字段的验证

9q78igpj  于 2022-11-26  发布在  Ruby
关注(0)|答案(6)|浏览(202)

我使用的是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]) }

这是他们正在验证的模型:

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 <top (required)>'

  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 <top (required)>'

我也尝试过在测试数组中使用字符串值,但我得到了同样的错误,我真的不明白它。

mefy6pfw

mefy6pfw1#

使用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) }
3lxsmp7m

3lxsmp7m2#

试试这个:
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
jchrr9hc

jchrr9hc3#

您的迁移可能是问题所在,它应该类似于:
t.integer :type, default: 1
您也可以考虑用另一种方法来测试它。
也许更像是:

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

9rnv2umw4#

使用shoulda匹配器沿着检查column_type。

it do
  should define_enum_for(:type).
    with_values(:receivable, :payable).
    backed_by_column_of_type(:integer)
end

it do 
  should define_enum_for(:category).
    with_values(:sale, :sale_with_tax, :fees, :lease, :tax_free, :other, :payroll).
    backed_by_column_of_type(:integer)
end
5jvtdoz2

5jvtdoz25#

只需使用shoulda matchers
it { should define_enum_for(:type).with_values([:receivable, :payable]) }
it { should define_enum_for(:category).with_values(:sale, :sale_with_tax, :fees, :lease, :tax_free, :other, :payroll)}

sr4lhrrt

sr4lhrrt6#

您的验证中包含以下字符串:

validates_inclusion_of :category, in: Invoice.categories.keys

enum的情况下
Invoice.categories.keys #=> ["sale", "sale_with_tax", "fees", "lease", "tax_free", "other", "payroll"]
您应该使用enum的其中一个名称更新对象数据。

相关问题