2013-08-20 12 views
22

ho avuto una classe, che è la base di alcune altre classi che si specializza il comportamento:test semplice STI con factorygirl

class Task < ActiveRecord::Base 
    attr_accessible :type, :name, :command 
    validates_presence_of :type, :name, :command 

    # some methods I would like to test 

end 

La classe CounterTask eredita da Task

class CounterTask < Task 
end 

Questa tutte le opere bene fino a quando sto provando a testare la classe base, dal momento che deve avere un tipo.

FactoryGirl.define do 
    factory :task do 
    sequence(:name) { |n| "name_#{n}" } 
    sequence(:command) { |n| "command_#{n}" } 
    end 
end 

Come testare la funzionalità di base della superclasse?

+3

Il test non deve essere scritto in modo da testarne la funzionalità piuttosto che l'implementazione? In questo caso ciò significherebbe che verificherai se 'CounterTask' ha gli attributi e altre cose che ottiene da' Task'. Se si modifica l'implementazione, ad esempio non si utilizza più STI. Il tuo test potrebbe ancora riuscire se il tuo 'CounterTask' mantiene lo stesso comportamento. – Arjan

+0

Questo è un buon punto. Ho solo pensato di salvare alcune duplicazioni nel test se prima testavo la funzionalità di base e poi le classi figlio ... Forse questa potrebbe essere la soluzione al mio problema. – Mark

risposta

48

È possibile dichiarare le definizioni di fabbriche come segue:

FactoryGirl.define do 
    factory :task, class: 'Task' do 
    shop 
    currency 
    value 10 
    end 

    factory :counter_task, parent: :task, class: 'CounterTask' do 
    end 
end 

E ora è possibile testare classe di base isolata dalla propria fabbrica e lo stesso per ogni classe ereditata.

+2

Avevo solo bisogno di passare l'opzione 'class' alla factory figlia per fare in modo che funzionasse:' factory: counter_task, class: 'CounterTask' do' (non era necessaria alcuna opzione 'class' per la factory madre). – gabe

+0

@gabe Omettere la 'classe: 'Task'' funziona anche per me, ma,' parent:: task' sembra essere significativo se si desidera che le proprietà definite nel blocco di attività vengano definite quando si utilizza counter_task. Quindi, con 'parent:: task',' build (: counter_task) .value == 10'. Se non si imposta il genitore, 'build (: counter_task) .value == nil'. – LiamD