我有一个{@ {1}}模型,它有has_one必需的User
。我想使用FactoryBot创建共享同一公司的多个用户。我看到了一些advice,我认为这是建议我在Company
块中创建Company对象,并将其用作用户的属性:
FactoryBot.define do
这似乎起初是可行的,除非我需要使用# In spec/factories/companies.rb
FactoryBot.define do
factory :company do
name { 'MyCompany' }
end
end
# In spec/factories/users.rb
FactoryBot.define do
company1 = FactoryBot.create(:company) # this will be shared by several users
factory :user1 do
first_name { 'Joe' }
last_name { 'Smith' }
company_id { company1.id }
end
factory :user2 do
first_name { 'Sam' }
last_name { 'Smith' }
company_id { company1.id }
end
end
在测试容器中从头开始重新创建数据库。当rake运行时,似乎初始化了我的工厂,并且rake db:create
步骤尝试运行,并且没有适当的数据库模式,所以它失败了:
FactoryBot.create(:company)
这使我认为我试图在错误的位置创建这些文件。
在哪里为我的测试数据设置诸如$ RAILS_ENV=test bundle exec rake db:rebuild
rake aborted!
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: relation "companies" does not exist
LINE 8: WHERE a.attrelid = '"companies"'::regclass
^
: SELECT a.attname, format_type(a.atttypid, a.atttypmod),
pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
c.collname, col_description(a.attrelid, a.attnum) AS comment
FROM pg_attribute a
LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
LEFT JOIN pg_type t ON a.atttypid = t.oid
LEFT JOIN pg_collation c ON a.attcollation = c.oid AND a.attcollation <> t.typcollation
WHERE a.attrelid = '"companies"'::regclass
AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum
之类的共享关联的最佳位置,以便它在我的应用正确初始化之后并且在我的测试套件执行之前发生?
FWIW,这是错误堆栈:
company1
答案 0 :(得分:2)
以这种方式创建对象时-每次初始化工厂时都会创建对象,无论是否在特定的测试运行中使用它们。
通常最好拥有独立的工厂,并在测试中明确声明您希望来自同一公司的两个用户:
let(:company){ create :company }
let(:user1){ create :user, company: company }
let(:user2){ create :user, company: company }
对于那些您不关心确切关系而只想重用一些有效值并避免级联的情况-create_default
gem中有一种test-prof
解决方法(请参阅更多here)< / p>