Rspec:工厂女工与复杂协会
Rspec: Factory Girl & Complex Associations
我正在尝试测试一种辅助方法,该方法将 return Subscribers
和 Campaign
的目标数量。作为 TDD 的新手,我很难思考如何编写这个,因为关联非常复杂。 Campaign
"targets" 根据订阅者是否在目标 plan
上并选择加入目标 program
。
如何让我的 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
这里是工厂..
spec/factories/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
spec/factories/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
...和我的规格..
spec/helpers/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
作为初学者,为了简单地测试我在上面通过对象 ID 创建的关联,我添加了第一个规范 - 但我什至无法让它通过。知道我可能遗漏了什么吗?
失败:
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)>'
更新
我尝试在我的 campaign
工厂中使用 Factory Girl association
..
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
我尝试将名称更改为随机名称,但仍然出现此错误。
您没有显示如何您的测试失败,这使得提供帮助有点困难,但您正在比较 plan_id
和 @plan
对象。尝试将 @campaign.plan_id
更改为 @campaign.plan
.
campaign = create(:campaign, plan_id: @plan, program_id: @program)
尝试更改为:
subject(:campaign) { create(:campaign, plan: plan, program: program) }
也可以用 id 来做,只要你是结果。
我打错了:
subject(:campaign) { create(:campaign, plan_id: plan_id, program_id: program_id) }
应该是:
subject(:campaign) { create(:campaign, plan_id: plan.id, program:id: program.id) }
我正在尝试测试一种辅助方法,该方法将 return Subscribers
和 Campaign
的目标数量。作为 TDD 的新手,我很难思考如何编写这个,因为关联非常复杂。 Campaign
"targets" 根据订阅者是否在目标 plan
上并选择加入目标 program
。
如何让我的 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
这里是工厂..
spec/factories/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
spec/factories/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
...和我的规格..
spec/helpers/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
作为初学者,为了简单地测试我在上面通过对象 ID 创建的关联,我添加了第一个规范 - 但我什至无法让它通过。知道我可能遗漏了什么吗?
失败:
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)>'
更新
我尝试在我的 campaign
工厂中使用 Factory Girl association
..
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
我尝试将名称更改为随机名称,但仍然出现此错误。
您没有显示如何您的测试失败,这使得提供帮助有点困难,但您正在比较 plan_id
和 @plan
对象。尝试将 @campaign.plan_id
更改为 @campaign.plan
.
campaign = create(:campaign, plan_id: @plan, program_id: @program)
尝试更改为:
subject(:campaign) { create(:campaign, plan: plan, program: program) }
也可以用 id 来做,只要你是结果。
我打错了:
subject(:campaign) { create(:campaign, plan_id: plan_id, program_id: program_id) }
应该是:
subject(:campaign) { create(:campaign, plan_id: plan.id, program:id: program.id) }