1

Ist das eine richtige Art und Weise ein Modell, Fabrik und Spezifikationen für ein Modell mit zwei alternativen Validierungen (weder beide haben Wert noch, beide gleich Null?Wie schreibt man Spezifikationen für ein Modell, das nur eines der beiden Attribute validiert (xor)?

Ich habe es die folgende Art und Weise sein könnte, zu schreiben, die funktioniert Recht. Allerdings ist nicht sicher, dass dies könnte die eleganteste Art und Weise tun.

model/invoice.rb

class Invoice < ActiveRecord::Base 
    validates :payment_term, presence: true, allow_nil: true 
    validates :interest_on_arrears, numericality: true, allow_nil: true 
    validate :choose_xor_date 
    private 
    def choose_xor_date 
    unless deadline.blank?^payment_term.blank? 
     errors.add(:base, 'specify a deadline or a payment term. 
     Not both empty, nor both filled') 
    end 
    end 
end 

model/invoice_spec.rb

RSpec.describe Invoice, type: :model do 
    describe 'validations' do 
    it 'fails validation with both deadline and payment_term filled' do 
     invoice_with_deadline = build(:invoice, deadline: '2016-02-20', payment_term: '') 
     invoice_with_payment_term = build(:invoice, deadline: '', payment_term: '2') 
     invoice_with_deadline_and_payment_term = 
     build(:invoice, deadline: '2016-02-20', payment_term: '2') 
     expect(invoice_with_deadline).to be_valid 
     expect(invoice_with_payment_term).to be_valid 
     expect(invoice_with_deadline_and_payment_term).to be_invalid 
    end 
    end 
end 

Fabriken/invoice.rb

FactoryGirl.define do 
    factory :invoice do 
    deadline "2016-02-20" 
    payment_term "2" 
    end 
end 

Funktionen/invoice_feature_spec.rb

# User create with parameter when creating invoice local object. 
describe 'when user has invoice' do 
    @invoice = create(:invoice, deadline: '2016-02-20', payment_term: '') 
    visit invoices_path 
    click_link I18n.t('button.show') 
end 
+0

bitten Sie Ihre Frage so klar wie möglich angeben? –

+0

Viel klarer, danke. –

Antwort

0

Sie sind fast da. Hier ist, was ich tun würde anders:

Im Modell nur ein paar Kommentare zur Namensgebung:

  • Es ist „in Verzug“, nicht „auf Rückstände“.
  • Ich denke, validate_deadline_xor_payment_term oder validate_deadline_or_payment_term_chosen wäre bessere Namen für die Validierungsmethode. "Choice" ist eigentlich eine gute englische Übersetzung von XOR.

Im Modell spec,

  • Die einzelne spec, die Sie bereits drei Spezifikationen, in jedem Gegenstand und Erwartung sein sollten.
  • Sie benötigen eine vierte Spezifikation, um zu testen, ob das Modell ungültig ist, wenn keines der Felder festgelegt ist.
  • Sie setzen alle optionalen Werte explizit richtig ein, so dass Sie leicht sehen können, was sie sind. Wenn Sie Ihre Fabrik wie unten beschrieben geändert haben, können Sie die leeren entfernen.

In der Fabrik würde ich die Standardwerte entfernen. Wenn ein Wert optional ist, sollte die Fabrik mit dem nicht qualifizierten Namen nicht den optionalen Wert haben. Es ist einfach für den Leser, sich an diese Konvention zu erinnern, und es macht Sinn, dass ein unspezifizierter Wert gleich null ist. Wenn für eine Fabrik mit einem nicht qualifizierten Namen ein optionaler Wert festgelegt wurde, kann der Leser nicht wissen, um welchen Wert es sich handelt.

Das Feature spec

  • in einem it Block sein sollte, kein describe Block. Eigentlich, da es a feature spec ist, würde es noch besser lesen, um das gesamte Feature in einem feature Block zu umgeben und scenario für dieses Beispiel zu verwenden.
  • Bedürfnisse Erwartungen über das, was auf der Indexseite ist (expect(page).to have_content und dergleichen)
  • Bedürfnisse Erwartungen über das, was auf der Messe Seite ist