2015-04-21 9 views
11

Używam Rails 4 teksty stałe i chcę, aby prawidłowo je przetestować, więc ustawić te testy się na mój pól ENUM:Rails - Zatwierdzenie badania pól enum

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]) } 

i jest to model oni Re walidacji:

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 

Ale kiedy uruchomić testy uzyskać:

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)>' 

ja również próbowałem z ciągów znaków na tablicach testowych, b ut Mam ten sam błąd i naprawdę go nie rozumiem.

+1

To pytanie jest duplikatem http://stackoverflow.com/questions/25597031/rails-4-enum-validation. Jak słusznie stwierdza Albertis: "Nie jestem pewien, czy ta walidacja ma sens, ponieważ próba przypisania nieprawidłowej wartości do statusu wywołuje argument ArgumentError" – ctc

+0

Może nie być spokrewniony, ale zdecydowanie ciekawy odczyt: [Używanie Enum jako abstrakcji podczas testowania] (http://craftingruby.com/posts/2015/07/07/using-enumerable-as-abstraction-when-testing.html) – onebree

Odpowiedz

6

Korzystanie dopasowujących shoulda możemy użyć następujących przetestować wyliczenia

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) } 
2

Spróbuj tego:

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

Dodatkowo do kodu-cleanup, spróbuj umieścić poprawne kategorie/typy w analogicznym stałej. Przykład:

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

Ten sam problem z rozwiązaniem, dzięki za porady dotyczące czyszczenia. – 8vius

2

migracji może być problem, powinno to wyglądać mniej więcej tak:

t.integer :type, default: 1

Można również rozważyć badanie to inny sposób.

Może raczej:

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

Migracja wygląda tak samo, domyślnie 0, ponieważ zaczynają się od niej. I nie uważał tego w ten sposób, może wystarczyć. – 8vius

+0

najlepiej używać nowej składni Rspec (opinia) i lepiej testować poprawność niż bezpośrednio testować włączenie w takich przypadkach. –

0

masz ten ciąg w swoim walidacji:

validates_inclusion_of :category, in: Invoice.categories.keys 

w przypadku wyliczenia Invoice.categories.keys # => [ "sprzedaż", "sale_with_tax" , "opłaty", "dzierżawa", "bez podatku", "inne", "lista płac"]

Powinieneś zaktualizować swoje dane obiektu jedną z nazw swoich wyliczanek.