在我的rails应用程序中,我有三个对象,我想为特定的Rspec测试建模。这些是组织,用户和销售机会。
class Organization
has_many :users
end
class User
has_many :sales_opportunities
end
组织必须具有唯一的名称,并且要使我的应用程序的授权/身份验证方面起作用,两个用户都需要属于同一个组织。出于此测试的目的,我希望一个用户为admin,另一个为非admin。
这在我的应用程序的其他部分成功运行(例如注册 - 第一个用户自动为管理员,后续用户不是,并且用于查看页面上的链接等)。但是,我现在需要做的是创建两个用户(两个属于一个组织),使其中一个成为管理员,然后当我删除 sales_opportunity 非管理员用户时,任何属于此非的sales_opportunities -admin用户应将所有权转移给管理员(用于重新分配)。
FWIW我正在使用其他一些测试的关联 - 但在这种情况下,我无法创建与一个组织关联的两个用户,所以我已经使用过:
before(:create) do |organization|
organization.users << FactoryGirl.build(:user ...admin params)
organization.users << FactoryGirl.build(:user ...non_admin params)
end
在工厂中为组织构建2个用户,这两个用户都属于一个组织并具有不同的特征。这很有效。
如果我尝试在工厂之前添加另一个(:create)然后构建一个sales_opportunity则失败(因为用户尚未创建但我相信)。在(:create)之后,陈述也会持平。我也尝试在测试中自己定义non_admin用户(例如,使用let(:non_admin)= Organization.users.last然后使用non_admin.sales_opportunities.create语句),但这无法产生任何销售机会(不确定它是做什么的。)
有没有关于如何构建这样的测试的好资源?我可以编写代码来立即解决问题 - 我似乎浪费了大量的时间来编写测试。我确定这些都不是特别干,要么通过我的工厂。
任何帮助都将不胜感激。
答案 0 :(得分:1)
:
FactoryGirl.define do
sequence(:name) { |n| "Sales Oppotunity - #{n}" }
factory :sales_opportunity do
user
name { generate(:name) }
# add more attributes here
end
end
rspec / factories / users.rb 中的:
FactoryGirl.define do
factory :user do
organization
sequence(:name) { |n| "Test user #{n}" }
sequence(:email) { |n| "test.user#{n}@example.com" }
password "password"
admin false
# add more attributes here
end
factory :admin_user, parent: :user do
admin true
end
factory :user_with_sales_opportunities, parent: :user, traits: [:with_sales_opportunity]
factory :admin_user_with_sales_opportunities, parent: :admin_user, traits: [:with_sales_opportunity]
trait :with_sales_opportunity do
ignore do # instead of ignore use transient if you're using factory girl 4.3 or above
sales_opportunities_count 5
end
after(:create) do |user, evaluator|
sales_opportunities { FactoryGirl.create_list(:sales_opportunity, evaluator.sales_opportunities_count, user: user) }
end
end
end
rspec / factories / organizations.rb 中的:
FactoryGirl.define do
sequence(:name) { |n| "Organization - #{n}" }
factory :organization do
name { generate(:name) }
ignore do
users_count 5
admin_users_count 2
sales_opportunities_count 5
end
after(:create) do |organization, evaluator|
users { FactoryGirl.create_list(:user_with_sales_opportunities, evaluator.users_count, organization: organization, sales_opportunities_count: sales_opportunities_count) + FactoryGirl.create_list(:admin_user_with_sales_opportunities, evaluator.users_count, organization: organization, sales_opportunities_count: sales_opportunities_count) }
end
# add more attributes here
end
end
现在你可以:
let(:organization) { FactoryGirl.create(:organization, users_count: 4, admin_users_count: 3, sales_opportunities_count: 4) }
答案 1 :(得分:0)
我不确定您要做什么,因为您似乎正在删除要转移的销售机会?
如果您认为它是一个rspec,您可以尝试在(:build)之后使用
类似的东西:
factory :user, class: User do
sequence(:email) { |n| "user#{n}@example.org" }
password "foobar"
# Standard user stuff etc
trait :admin do
after(:build) do |user|
user.set_admin
end
end
end
factory :organisation, class: Organisation do
name "Super Duper"
after(:build) do |organization|
organization.users << FactoryGirl.build(:user)
organization.users << FactoryGirl.build(:user, :admin)
end
end
我觉得你可能有一个建模问题。您的销售机会不应该是独立的吗?
即:
class SalesOpportunity
field :name, type: String
field :phone, type: Integer
belongs_to :user
end
class User
field :name, type: String
field :phone, type: Integer
has_many :salesopportunities
end
这样您可以删除用户对象并保留销售机会吗?