【问题标题】:Rails - Test validation of enum fieldsRails - 枚举字段的测试验证
【发布时间】:2015-06-29 01:57:05
【问题描述】:

我正在使用 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)>'

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

【问题讨论】:

标签: ruby-on-rails validation rspec enums


【解决方案1】:

使用 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

【讨论】:

    【解决方案2】:

    只需使用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)}

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        你的验证中有这个字符串:

        validates_inclusion_of :category, in: Invoice.categories.keys
        

        如果是枚举 Invoice.categories.keys #=> ["sale", "sale_with_tax", "fees", "lease", "tax_free", "other", "payroll"]

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

        【讨论】:

          【解决方案5】:

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

          t.integer :type, default: 1

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

          也许更像:

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

          【讨论】:

          • 迁移看起来相同,只是默认为 0,因为值从那里开始。并没有那样考虑,可能就足够了。
          • 最好使用新的 Rspec 语法(观点),并且在此类情况下最好测试有效性而不是直接测试包含。
          【解决方案6】:

          试试这个:

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

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

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

          【讨论】:

          • 您的解决方案存在同样的问题,不过感谢您的清理提示。
          猜你喜欢
          • 1970-01-01
          • 2014-10-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-07-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多