2013-08-20 3 views
22

У меня есть класс, который является основой некоторых других классов, которая специализируется на поведение:Тестирование простой STI с FactoryGirl

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

    # some methods I would like to test 

end 

Класс CounterTask наследует от задачи

class CounterTask < Task 
end 

Это все работает до тех пор, пока я не попытаюсь проверить базовый класс, так как он должен иметь тип.

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

Как бы вы протестировали основные функции суперкласса?

+3

Разве ваш тест не должен быть написан так, чтобы он тестировал функциональность, а не реализацию? В этом случае это означало бы, что вы проверите, имеет ли атрибут «CounterTask» атрибуты и другие вещи, которые он получает из «Задачи». Если вы измените свою реализацию, например, не используете STI. Ваш тест все равно может быть успешным, если ваша «CounterTask» сохраняет такое же поведение. – Arjan

+0

Это хороший момент. Я просто подумал, что я сохраню некоторые дубликаты в тесте, если я сначала испытаю базовую функциональность, а затем дочерние классы ... Возможно, это может быть решением моей проблемы. – Mark

ответ

48

Вы можете объявить определение заводов следующим образом:

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

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

И теперь вы можете проверить базовый класс изолированного от своего завода и того же для каждого наследуемого класса.

+2

Мне нужно было передать опцию 'class' на дочернюю фабрику, чтобы сделать эту работу:' factory: counter_task, class: 'CounterTask' do' (для родительской фабрики не требуется опция 'class'). – gabe

+0

@gabe Опуская «класс:« Задача », также работает для меня, но« parent:: task »кажется значительным, если вы хотите, чтобы свойства, определенные в блоке задач, определялись при использовании counter_task. Итак, с 'parent:: task',' build (: counter_task) .value == 10'. Если вы не установите родительский элемент 'build (: counter_task) .value == nil'. – LiamD

Смежные вопросы