2015-06-16 4 views
0

Я пытаюсь проверить вспомогательный метод, который бы возвращал сумму Subscribers, на которую нацелен Campaign. Будучи довольно новым для TDD, мне сложно свернуть голову вокруг того, как писать это, поскольку ассоциации довольно сложны. A Campaign «указывает» на то, является ли абонент на целевом plan и включен в целевой адрес program.Rspec: Factory Girl & Complex Associations

Как я могу связать объекты Factory Girl друг с другом, чтобы продолжить писать спецификацию? Как бы это ни казалось, я не могу заставить их сотрудничать.

Вот модельные ассоциации ..

модели/campaign.rb

class Campaign < ActiveRecord::Base 
    belongs_to :program 
    belongs_to :plan 
end 

модели/subscriber.rb

class Subscriber < ActiveRecord::Base 
    has_many :plans, through: :plannables 
end 

модели/plan.rb

class Plan < ActiveRecord::Base 
    has_many :subscribers, through: :plannables 
    has_many :plannables 
    has_many :campaigns 

    validates :name, presence: true, 
       uniqueness: true 
end 

модели/program.rb

class Program < ActiveRecord::Base 
    has_many :campaigns 

    validates :name, presence: true, 
        uniqueness: true 
end 

модели/plannable.rb

class Plannable < ActiveRecord::Base 
    belongs_to :plans 
    belongs_to :subscribers 
end 

Вот заводы ..

спецификации/фабрики/campaign.rb

FactoryGirl.define do 

    factory :campaign do |x| 
     x.sequence(:name) { |y| "201#{y} Example" } 
     x.sequence(:comment) { |y| "The #{y} example" } 
     channels ["Folder", "Fax"] 
    end 

    factory :program do 
     name "Sims" 
     comment "the sims program" 
    end 

    factory :plan do 
     name "PDX" 
    end 
end 

спецификации/фабрики/subscribers.rb

FactoryGirl.define do 
    sequence(:first_name) { |y| "Sam #{y}" } 
    sequence(:last_name) { |y| "Sm#{y}th" } 
    sequence(:email) { |y| "email#{y}@sub.com".downcase } 

    factory :subscriber do 
     first_name 
     last_name 
     email 
     password "secret123" 
     home_duid { SecureRandom.uuid } 
     admin false 
     sims true #opt-in status 
     cups false #opt-in status 
     tire false #opt-in status 
    end 


end 

.. . и мои спецификации ..

спецификации/хелперы/application_helper_spec.rb

require "rails_helper" 

RSpec.describe ApplicationHelper, :type => :helper do 
    before :all do 
     @program = create(:program) 
     @subscriber = create(:subscriber, star: true) 
     @campaign = create(:campaign, plan_id: @plan, program_id: @program) 
     @plan = Plan.new(name: "STX)", subscriber_id: @subscriber) 
    end 

    describe "Campaign subscriber listing" do 
     it "finds subscribers that opt-in to affiliated program" do 
      expect(@campaign.plan_id).to eq @plan 
     end 
    end 
end 

Подобно тому, как стартер, чтобы просто проверить ассоциацию я создал выше с помощью объектных идентификаторов, я добавил, что первый спецификации - но я не могу даже Получите это, чтобы пройти. Любая идея, что мне может не хватать?

Неудача:

1) ApplicationHelper Campaign subscriber listing finds subscribers that opt-in to affiliated program 
    Failure/Error: expect(campaign.plan).to eq plan 

     expected: #<Plan id: 3, name: "PDX", created_at: "2015-06-16 20:51:18", updated_at: "2015-06-16 20:51:18", plan_id: nil> 
      got: nil 

     (compared using ==) 
    # ./spec/helpers/application_helper_spec.rb:19:in `block (3 levels) in <top (required)>' 

UPDATE

Я попытался с помощью Factory Girl association в моем campaign заводе ..

factory :campaign do |x| 
    x.sequence(:name) { |y| "201#{y} Example" } 
    x.sequence(:comment) { |y| "The #{y} example" } 
    channels ["Folder", "Fax"] 
    association plan 
end 

Но получает запутанную ошибку ...

* plan - Validation failed: Name has already been taken 

Я попытался изменить имя на случайное, но продолжаю получать эту ошибку.

+1

Использование '@ instance_variables' очень тяжело. Предпочитаете использовать '' 'let (: program) {create (: program)}' '' или '' 'subject (: program) {create (: program)}' ''. 'let' лениво загружен. – davidwessman

+0

@ davidwessman - Спасибо! Я сделаю эти изменения. – shroy

+0

Как вы думаете, вы можете уточнить свой другой вопрос? Что вы хотите сделать в своем тесте? – davidwessman

ответ

2
campaign = create(:campaign, plan_id: @plan, program_id: @program) 

Try изменения в:

subject(:campaign) { create(:campaign, plan: plan, program: program) } 

бы также работать, чтобы сделать это с идентификаторами, до тех пор, как вы следствие.

Я сделал опечатку здесь:

subject(:campaign) { create(:campaign, plan_id: plan_id, program_id: program_id) } 

Должно быть:

subject(:campaign) { create(:campaign, plan_id: plan.id, program:id: program.id) } 
+0

Это сработало! Спасибо! – shroy

0

Вы не показали как ваше испытание это не удается, что делает его немного трудно помочь, но вы сравниваете plan_id против @plan объекта. Попробуйте изменить @campaign.plan_id на @campaign.plan.

+0

Эй, Энди, я внес изменения, которые вы предложили, и разместил сообщение об ошибке выше. Это почти то же самое, что я получал при использовании '@ campaign.plan_id'. – shroy

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